1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include<iostream> #include<string> #include<cstring> #include<algorithm> using namespace std; int n, m; bool prime[10000005]; int main(){ memset(prime, true, sizeof(prime)); cin >> n >> m; prime[0] = prime[1] = false; for (int i = 2; i <= n; i++) { if (!prime[i])continue; for (int j = 2 * i; j <= n; j += i) { prime[j] = false; } } for (int i = 1; i <= m; i++) { int tmp; cin >> tmp; cout << (prime[tmp]?"Yes":"No") << endl; } } |
标签归档:洛谷
洛谷 P3367 【模板】并查集
明明记得之前应该有并查集的板子在博客里?怎么找不到了??
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include<iostream> #include<string> #include<cstring> #include<algorithm> using namespace std; int father[10005]; int _find(int num) { if (father[num] == -1)return num; else return father[num] = _find(father[num]); } void _union(int v1, int v2) { if (_find(v1) == _find(v2))return; father[_find(v2)] = v1; } int n, m; int main(){ memset(father, -1, sizeof(father)); cin >> n >> m; while (m--) { int z, x, y; cin >> z >> x >> y; if (z == 1)_union(x, y); else cout << (_find(x) == _find(y) ? 'Y' : 'N') << endl; } } |
洛谷 P1020 导弹拦截
又是自己改了半天的一道题,忘了……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include<iostream> #include<string> #include<algorithm> using namespace std; int n=1; int arr[100005]; int f[100005]; int f2[100005]; int main() { while (cin >> arr[n])n++; n--; arr[0] = 50001; f[0] = 0; for (int i = 1; i <= n; i++) { int m = f[0]; for (int j = 1; j < i; j++) { if (f[j]>m&&arr[j]>=arr[i]) { m = f[j]; } } f[i] = m + 1; } cout << *max_element(f+1,f+n+1) << endl; arr[0] = 0; f2[0] = 0; for (int i = 1; i <= n; i++) { int m = f2[0]; for (int j = 1; j < i; j++) { if (f2[j]>m&&arr[j]<arr[i]) { m = f2[j]; } } f2[i] = m + 1; } cout << *max_element(f2+1,f2+n+1) << endl; } |
洛谷 P1233 木棍加工
不好做啊……想不出来……看题解……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include<iostream> #include<string> #include<algorithm> using namespace std; int n; struct node { int l, w; bool operator < (const node& n2) const { if (l != n2.l)return l > n2.l; if (w != n2.w)return w > n2.w; return false; } }arr[5005]; bool visited[5005]; int main() { cin >> n; for (int i = 1; i <= n; i++) { cin >> arr[i].l >> arr[i].w; } sort(arr + 1, arr + n + 1); bool flag = false; int cnter = 0, ptr = 0; do { flag = false; for (ptr=1;ptr <= n; ptr++) { if (!visited[ptr]) { flag = true; visited[ptr] = true; break; } } if (!flag)break; cnter++; for (int i = ptr+1; i <= n; i++) { if (visited[i] || arr[i].l > arr[ptr].l || arr[i].w > arr[ptr].w) continue; visited[i] = true; ptr = i; } } while (flag); cout << cnter; } |
洛谷 P1080 国王游戏
这题不好写,一个问题在贪心怎么排序,再有的难点就是高精乘/除,都不好写。。
这次正经的写了个高精度乘/除。。留下来备用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | #include<iostream> #include<string> #include<algorithm> using namespace std; int n; struct bigInt { //For Non-negative Numbers private: string v; static string & bIsort(string & v) { //each char has reduced '0' for (int i = 0; i < v.length(); i++) { if (v[i] > 9) { if (i == v.length() - 1)v.append(1, v[i] / 10); else v[i + 1] += v[i] / 10; v[i] %= 10; } } return v; } static string lng2str(long long v) { string s = ""; while (v) { s.append(1, v % 10 + '0'); v /= 10; } reverse(s.begin(), s.end()); return s; } static string& trimPre0(string& v3) { while (v3.length() != 0 && (*v3.begin()) == '0')v3.erase(v3.begin()); if (v3.length() == 0)v3 = "0"; return v3; } public: bigInt() { v = "0"; } bigInt(long long n) { v = lng2str(n); } bigInt(string s) { v = s; } bigInt& operator = (const bigInt & bI) { this->v = bI.v; return *this; } bigInt operator * (bigInt bI2) const { string v1 = v, v2 = bI2.v; if (v2.length() > v1.length())swap(v1, v2); reverse(v1.begin(), v1.end()); reverse(v2.begin(), v2.end()); string v3 = ""; for (int i = 0; i < v1.length(); i++)v1[i] -= '0'; for (int i = 0; i < v2.length(); i++)v2[i] -= '0'; v3.resize(v1.length() + v2.length(), 0); for (int i = 0; i < v2.length(); i++) { for (int j = 0; j < v1.length(); j++) { v3[i + j] += v2[i] * v1[j]; } bIsort(v3); } for (int i = 0; i < v3.length(); i++)v3[i] += '0'; reverse(v3.begin(), v3.end()); trimPre0(v3); return bigInt(v3); } bigInt operator / (long long bI2) const { string v1 = v; for (int i = 0; i < v1.length(); i++)v1[i] -= '0'; long long v2 = bI2; string v3 = ""; long long div = 0; for (int i = 0; i < v1.length(); i++) { div *= 10; div += v1[i]; if (div < v2) { v3.append(1, '0'); continue; } v3.append(lng2str(div / v2)); div %= v2; } return bigInt(trimPre0(v3)); } bool operator < (bigInt bI2) const { if (v.length() != bI2.v.length())return v.length() < bI2.v.length(); for (int i = 0; i < v.length(); i++) { if (v[i] != bI2.v[i])return v[i] < bI2.v[i]; } return false; } friend istream& operator >> (istream& in, bigInt& bI) { in >> bI.v; return in; } friend ostream& operator << (ostream& out, bigInt& bI) { out << bI.v; return out; } }; struct p { bigInt a; int b; bool operator < (const p& p2) { return a * b < p2.a*p2.b; } }ps[1005]; int main() { cin >> n; for (int i = 1; i <= n + 1; i++) { cin >> ps[i].a >> ps[i].b; } sort(ps + 2, ps + n + 2); bigInt multiply = ps[1].a; bigInt mmax("0"); for (int i = 2; i <= n + 1; i++) { mmax = max(mmax, multiply / ps[i].b); multiply =multiply* ps[i].a; } cout << mmax; } |
洛谷 P1338 末日的传说
可以说是超难的一道题了。。。。
全程题解:
https://www.luogu.org/blog/user11765/solution-p1338
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include<iostream> #include<algorithm> using namespace std; long long n, m, a[50005]; int main() { cin >> n >> m; long long s = 1, e = n; for (long long i = 1; i <= n; i++) { long long t = (n - i)*(n - i - 1) / 2; if (t >= m)a[s++] = i; else { a[e--] = i; m -= e - s + 1; } } for (int i = 1; i <= n; i++)cout << a[i] << " "; } |
洛谷 P1582 倒水 题解
题目描述
一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水。接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子。每次他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒进另一个里,然后把空瓶丢弃。(不能丢弃有水的瓶子)
显然在某些情况下CC无法达到目标,比如N=3,K=1。此时CC会重新买一些新的瓶子(新瓶子容量无限,开始时有1升水),以到达目标。
现在CC想知道,最少需要买多少新瓶子才能达到目标呢?
输入输出格式
输入格式:
一行两个正整数, N,K。
输出格式:
一个非负整数,表示最少需要买多少新瓶子。
这道题很有意思,所以要在这里好好的写一下题解。
由“开始时每个瓶子里有1升水”和“新瓶子容量无限,开始时有1升水”、“他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒进另一个里”,很容易联想到但凡不是空瓶子,每个瓶子里水的数量一定都是以2为底的幂,如1、2、4、8、16、32、64……等等。由此我们可以将这些数字放到二进制视角下来思考。
由题中说“他决定保留不超过K个瓶子”,可将其转化为“CC最终所具有的瓶子总数 n_f 在二进制表示形式下有总计不超过K个1”。
(下面说的所有东西可能都不太好想,请认真思考。)
然而我们需要买空瓶子……所以结果的数字只能大不能小,因此我们需要通过去除数字末尾的1,保留数字前面的1来使数字达到要求。
除了Lowbit之外,我还有一种做法(这个做法其实就是Lowbit和加综合起来的底层实现)。这个做法分为三步:
1、找到数字中倒数第一个1.
2、把接下来从后向前连续的所有1变成0.
3、再把接下来不是1的第一个0变成1.
举例:原数:001011
第二步完成后:001000
第三步完成后:001100
重复进行这一操作,直到满足要求“瓶子总数 n_f 在二进制表示形式下有总计不超过K个1”即可。
程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include<iostream> #include<algorithm> #include<cstdio> #include<string> #include<deque> #include<map> #include<cstring> using namespace std; inline int & setBit(int & v, int sv, int p) { if (sv) { v |= 1 << p; } else { v &= ~(1 << p); } return v; } inline int getBit(int v, int p) { return (v >> p) & 1; } bool checkBits(int value, int num) { int cnt = 0; for (int i = 0; i < 32; i++) { cnt += getBit(value, i); } return cnt <= num; } int main() { int n, k; cin >> n >> k; int no = n; while (!checkBits(n, k)) { int ptr = 0; while (!getBit(n, ptr))ptr++; while (getBit(n, ptr)) { setBit(n, 0, ptr); ptr++; } setBit(n, 1, ptr); } cout << n-no; } |
洛谷 P1164 小A点菜
这动规没见过,不好做……参考题解了……
https://www.luogu.org/blog/DEDSECspace/solution-p1164
https://www.luogu.org/blog/6-28318530717958/solution-p1164
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include<iostream> #include<algorithm> #include<cstdio> #include<string> #include<deque> #include<map> #include<cstring> using namespace std; int n, m; int A[105]; int f[10005]; int main() { cin >> n >> m; for (int i = 1; i <= n; i++)cin >> A[i]; f[0] = 1; for (int i = 1; i <= n; i++) { for (int j = m; j >= A[i]; j--) { f[j]+= f[j - A[i]]; } } cout << f[m]; } |
洛谷 P1060 开心的金明
Ver1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include<iostream> #include<algorithm> #include<cstdio> #include<string> #include<deque> #include<map> #include<cstring> using namespace std; int n, m; int v[30],w[30];//乘积,价格 int f[30][30005]; //物品,钱数 int main() { cin >> n >> m; for (int i = 1; i <= m; i++) { int tmp2; cin >> w[i] >> tmp2; v[i] = w[i] * tmp2; } for (int i = 1; i <= m; i++) { for (int j = 0; j <= n; j++) { if(j>=w[i])f[i][j] = max(f[i - 1][j], f[i - 1][j - w[i]] + v[i]); else f[i][j] = f[i - 1][j]; } } int mmax = 0; for (int i = 0; i <= n; i++) { mmax = max(mmax, f[m][i]); } cout << mmax; } |
Ver2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include<iostream> #include<algorithm> #include<cstdio> #include<string> #include<deque> #include<map> #include<cstring> using namespace std; int n, m; int v[30],w[30];//乘积,价格 int f[30005]; //钱数 int main() { cin >> n >> m; for (int i = 1; i <= m; i++) { int tmp2; cin >> w[i] >> tmp2; v[i] = w[i] * tmp2; } for (int i = 1; i <= m; i++) { for (int j = n; j >=w[i]; j--) { f[j] = max(f[j], f[j - w[i]] + v[i]); } } int mmax=0; for (int i = 0; i <= n; i++) { mmax = max(mmax, f[i]); } cout << mmax; } |
洛谷 P1030 求先序排列
这类型的题(给中序和前后任一个,让求另外一个的)已经做了不下3、4遍了。。
再贴出来,代码风格可能会不大一样。。。应该是相比之前的有很多改进的。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #include<iostream> #include<algorithm> #include<cstdio> #include<string> #include<deque> #include<map> #include<cstring> using namespace std; struct node { char l, r; node() { l = r = '*'; } node(char l1, char r1) { l = l1; r = r1; } }; map<char, node> dic; string in, post; inline int searchInTraversal(char v, int s, int e) { for (int i = s; i <= e; i++)if (in[i] == v)return i; return -1; } char buildTree(int is, int ie,int ps,int pe) { char father = post[pe]; if (is == ie && ps == pe) { dic[father] = node(); return father; } if (is > ie || ps > pe) { return '*'; } int posOfF = searchInTraversal(father, is, ie); int lTreeLen = posOfF - is; char l = buildTree(is, posOfF - 1, ps, ps + lTreeLen - 1); char r = buildTree(posOfF + 1, ie, ps + lTreeLen, pe - 1); dic[father] = node(l, r); return father; } void preTraversal(char node) { if (node == '*')return; cout << node; preTraversal(dic[node].l); preTraversal(dic[node].r); } int main() { cin >> in >> post; char f=buildTree(0, in.length() - 1, 0, post.length() - 1); preTraversal(f); } |