题目链接:https://vjudge.net/contest/216713
两个月前,也就是寒假做的题。
据说是用来熟悉STL的水题,然而不熟练STL的我做得好艰难啊。
只按照书上的最低要求选做了一些,其他实在是懒得做…
例题5-1
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} const int maxn = 10000 + 10; int a[maxn]; int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int n, q, kase = 0; while(scanf("%d%d", &n, &q) && n && q) { printf("CASE# %d:\n", ++kase); for(int i = 0; i < n; i++) scanf("%d", &a[i]); sort(a, a + n); int x, flag; for(int i = 0; i < q; i++) { scanf("%d", &x); flag = 0; for(int j = 0; j < n; j++) { if(a[j] == x) { flag = 1; printf("%d found at %d\n", x, j + 1); break; } } if(!flag) printf("%d not found\n", x); } } return 0; }
例题5-2
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* vector<int> v[]相当于二维数组, 它的第一维大小固定,第二维大小不固定; 题目有四个指令,善于寻找他们的共同点 */ vector<int> v[30]; int n; //寻找x木块所在堆和高度,用引用返回 void Find(int x, int &p, int &h) { for(p = 0; p < n; p++) for(h = 0; h < v[p].size(); h++) if(v[p][h] == x) return; } //把x木块上面的木块归位,resize void POP(int x, int p, int h) { for(int i = h + 1; i < v[p].size(); i++) { int x = v[p][i]; v[x].push_back(x); } v[p].resize(h + 1); } //把a及上方木块移动到b上方 void Move(int a, int b, int pa, int ha, int pb, int hb) { for(int i = ha; i < v[pa].size(); i++) { int x = v[pa][i]; v[pb].push_back(x); } v[pa].resize(ha); } void Print() { for(int i = 0; i < n; i++) { cout << i << ':'; for(int j = 0; j < v[i].size(); j++) cout << ' ' << v[i][j]; cout << '\n'; } } int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); cin >> n; for(int i = 0; i < n; i++) v[i].push_back(i); string s1, s2; int a, b; while(cin >> s1 >> a >> s2 >> b) { int pa, ha, pb, hb; Find(a, pa, ha); Find(b, pb, hb); if(pa == pb || a == b) continue; if(s2 == "onto") POP(b, pb, hb); if(s1 == "move") POP(a, pa, ha); Move(a, b, pa, ha, pb, hb); } Print(); return 0; }
例题5-3
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 学会使用stringstream,迭代器iterator和set; set中各个元素不重复且有序 */ set<string> S; int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); string s, a; while(cin >> s) { for(int i = 0; i < s.length(); i++) { if(isalpha(s[i])) { if(s[i] >= 'A' && s[i] <= 'Z') s[i] = s[i] + 32; // s[i] = tolower(s[i]); } else s[i] = ' '; } stringstream ss(s); while(ss >> a) { S.insert(a); } } set<string>::iterator it; for(it = S.begin(); it != S.end(); it++) cout << *it << '\n'; return 0; }
例题5-4
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 开两个vector存原始单词和转换成小写后的单词; map可以计数 */ vector<string> words; vector<string> ans; map<string, int> num; string tra(string s) { string ans = s; for(int i = 0; i < ans.length(); i++) ans[i] = tolower(ans[i]); sort(ans.begin(), ans.end()); return ans; } int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); string s, a; while(cin >> s && s != "#") { words.push_back(s); a = tra(s); if(!num.count(a)) num[a] = 0; num[a]++; } for(int i = 0; i < words.size(); i++) { if(num[tra(words[i])] == 1) ans.push_back(words[i]); } sort(ans.begin(), ans.end()); for(int i = 0; i < ans.size(); i++) cout << ans[i] << '\n'; return 0; }
例题5-5
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 关键: set<int> Set; map<Set, int> ID; vector<Set> SET; 对于每一个Set s, ID[s]是ID,SET[ID[s]]是s本身。 */ typedef set<int> Set; map<Set, int> ID; vector<Set> SET; int Search(Set s) { if(!ID.count(s)) { SET.push_back(s); ID[s] = SET.size() - 1; } return ID[s]; } int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int T, n; scanf("%d", &T); while(T--) { stack<int> s; scanf("%d", &n); while(n--) { string p; cin >> p; if(p[0] == 'P') s.push(Search(Set())); else if(p[0] == 'D') s.push(s.top()); else { Set x1 = SET[s.top()]; s.pop(); Set x2 = SET[s.top()]; s.pop(); Set x; if(p[0] == 'U') set_union(x1.begin(), x1.end(), x2.begin(), x2.end(), inserter(x, x.begin())); else if(p[0] == 'I') set_intersection(x1.begin(), x1.end(), x2.begin(), x2.end(), inserter(x, x.begin())); else { x = x2; x.insert(Search(x1)); } s.push(Search(x)); } cout << SET[s.top()].size() << '\n'; } cout << "***" << '\n'; } return 0; }
例题5-6
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 要弄清题意 */ int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int T, kase = 1; while(scanf("%d", &T) && T) { queue<int> Q; queue<int> q[1010]; map<int, int> M; for(int i = 0; i < T; i++) { int n; scanf("%d", &n); while(n--) { int x; scanf("%d", &x); M[x] = i; } } printf("Scenario #%d\n", kase++); char s[10]; while(1) { scanf("%s", s); if(s[0] == 'S') break; else if(s[0] == 'E') { int x; scanf("%d", &x); int t = M[x]; if(q[t].empty()) Q.push(t); q[t].push(x); } else { int t = Q.front(); printf("%d\n", q[t].front()); q[t].pop(); if(q[t].empty()) Q.pop(); } } printf("\n"); } return 0; }
例题5-7
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* priority_queue<ll, vector<ll>, greater<ll> > pq; 优先队列,越大优先级越小,即从小到大排序。 若省略最后一个参数,则是从大到小。 */ int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); priority_queue<ll, vector<ll>, greater<ll> > pq; set<ll> S; //用于判断是否重复 pq.push(1); S.insert(1); for(int i = 1; ; i++) { ll x = pq.top(); pq.pop(); if(i == 1500) { printf("The 1500'th ugly number is %lld.\n", x); break; } ll y; y = 2 * x; if(!S.count(y)) { pq.push(y); S.insert(y); } y = 3 * x; if(!S.count(y)) { pq.push(y); S.insert(y); } y = 5 * x; if(!S.count(y)) { pq.push(y); S.insert(y); } } return 0; }
例题5-8
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 计算行列,模拟即可 */ string s[110]; const int maxn = 60; int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int n; while(cin >> n) { int M = 0; for(int i = 0; i < n; i++) { cin >> s[i]; M = max(M, (int)s[i].length()); } sort(s, s + n); int cols = (60 - M) / (M + 2) + 1; int rows = (n - 1) / cols + 1; for(int i = 0; i < maxn; i++) cout << '-'; cout << '\n'; for(int i = 0; i < rows; i++) { for(int j = 0; j < cols; j++) { int x = rows * j + i; if(x < n) { int len = s[x].length(); cout << s[x]; if(j == cols - 1) { for(int k = 0; k < M - len; k++) cout << ' '; } else { for(int k = 0; k < M + 2 - len; k++) cout << ' '; } } } cout << '\n'; } } return 0; }
例题5-9
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 直接枚举r1,r2,c1,c2肯定T 解决方法: 枚举c1,c2,然后从上到下扫描各行 把每行c1,c2列的内容存到map中 若已经存在,则找到 */ struct Node { int x, y; Node(int a, int b) { x = a; y = b; } bool operator < (const Node & b) const { if(x == b.x) return y < b.y; return x < b.x; } }; map<string, int> ID; //给每个字符串一个编号 vector<string> str; //保存编号对应的字符串 vector<int> v[10010]; //存处理好的int表格 map<Node, int> M; int IDD(string s) //获取编号 { if(ID.count(s)) return ID[s]; str.push_back(s); return ID[s] = str.size() - 1; } void solve(int n, int m) { for(int i = 0; i < m; i++) //i列 { for(int j = i + 1; j < m; j++) //j列 { M.clear(); for(int k = 0; k < n; k++) //k行 { Node node(v[k][i], v[k][j]); if(M.count(node)) { printf("NO\n"); printf("%d %d\n", M[node] + 1, k + 1); printf("%d %d\n", i + 1, j + 1); return; } else { M[node] = k; } } } } printf("YES\n"); } int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int n, m; while(~scanf("%d%d", &n, &m)) { string s; char ch = getchar(); for(int i = 0; i < n; i++) { while(1) { ch = getchar(); if(ch == '\n' || ch == '\r') { if(!s.empty()) v[i].push_back(IDD(s)); s.clear(); break; } if(ch == ',') { v[i].push_back(IDD(s)); s.clear(); } else { s = s + ch; } } } solve(n, m); //千万不能忘!!! for(int i = 0; i < n; i++) v[i].clear(); ID.clear(); str.clear(); } return 0; }
习题5-1
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 用getline读一行 用stringstream一个个读入 注意getline格式 */ vector<string> v[1010]; int a[200]; int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int i = 0, num = 0; string sin; while(getline(cin, sin)) { stringstream ss(sin); string s; while(ss >> s) v[i].push_back(s); i++; } //求第k个单词的最大长度存入a[] for(int j = 0; j < i; j++) { for(int k = 0; k < v[j].size(); k++) { a[k] = max(a[k], (int)v[j][k].length()); num = max(num, k); } } //输出,注意最后一列不用输出空格 for(int j = 0; j < i; j++) { for(int k = 0; k < v[j].size() - 1; k++) { cout << v[j][k]; for(int l = 0; l < a[k] - v[j][k].length(); l++) cout << ' '; cout << ' '; } cout << v[j][v[j].size() - 1] << '\n'; } return 0; }
习题5-2
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 题目保证1000步之内必定变成0或者循环,所以判断0即可 */ int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int a[2][20]; int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%d", &a[0][i]); } int j = 0; bool flag = false; for(int l = 0; l < 2000; l++) { bool zero = true; int k = j ? 0 : 1; for(int i = 0; i < n; i++) { int m = (i + 1) % n; a[k][i] = fabs(a[j][i] - a[j][m]); if(a[k][i] != 0) zero = false; } j = k; if(zero) { printf("ZERO\n"); flag = true; break; } } if(!flag) printf("LOOP\n"); } return 0; }
习题5-3
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 简单的队列操作 */ int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int n; while(~scanf("%d", &n) && n) { bool first = true; queue<int> q; for(int i = 1; i <= n; i++) q.push(i); printf("Discarded cards:"); while(1) { if(q.size() == 1) { printf("\nRemaining card: %d\n", q.front()); break; } int x = q.front(); if(first) { first = false; printf(" %d", x); } else printf(", %d", x); q.pop(); x = q.front(); q.pop(); q.push(x); } } return 0; }
习题5-4
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 要读懂题意!!! 题目意思是,申请a到b和b到a的数量一样就OK。 用数组,每输入两个数就交换 如果最后数组和原数组相同则OK a,b b,c c,a的情况也行 */ const int maxn = 500000 + 10; int arr[maxn]; int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int n; while(~scanf("%d", &n) && n) { for(int i = 0; i < n; i++) arr[i] = i; for(int i = 0; i < n; i++) { int a, b; scanf("%d%d", &a, &b); swap(arr[a], arr[b]); } bool flag = false; for(int i = 0; i < n; i++) { if(arr[i] != i) { flag = true; printf("NO\n"); break; } } if(!flag) printf("YES\n"); } return 0; }
习题5-5
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 枚举每一个单词 如果再枚举两个单词是否能拼成它,会超时 所以用substr把这个单词拆分 用map映射,在里面的单词映射成1,不在的0 */ const int maxn = 120000 + 10; map<string, bool> m; string s[maxn]; int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int n = 0; while(cin >> s[n]) { m[s[n++]] = 1; } string a, b; for(int i = 0; i < n; i++) { for(int j = 0; j < s[i].size() - 1; j++) { a = s[i].substr(0, j + 1); if(!m[a]) continue; b = s[i].substr(j + 1); if(!m[b]) continue; cout << s[i] << endl; break; } } return 0; }
习题5-6
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 做了很长时间,题目要求考虑不周,代码能力,还忘记初始化 */ struct node { int x, y; bool flag; //判断是否找到了对称点 bool operator < (const node &b) const { if(x == b.x) return y < b.y; return x < b.x; } }node[1010]; int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%d%d", &node[i].x, &node[i].y); node[i].x *= 2; //为了避免出现小数,横坐标都乘2 node[i].flag = false; //初始化!!! } sort(node, node + n); int mid = (node[0].x + node[n - 1].x) / 2; bool ok = true; for(int i = 0; i < n; i++) { if(node[i].x == mid) //在对称轴上 { node[i].flag = true; continue; } if(node[i].flag) //这点已经有对称点了 continue; if(!ok) //存在点没有对称轴 break; int a = 2 * mid - node[i].x; for(int j = n - 1; j > 0; j--) { if(i == j) //同一点 continue; if(node[j].flag) //这点已经有对称点了 continue; if(node[j].x == a) { if(node[j].y == node[i].y) { node[j].flag = true; node[i].flag = true; break; } else continue; } else if(node[j].x < a) { ok = false; break; } else continue; } } bool yes = true; if(!ok) { printf("NO\n"); yes = false; } else { for(int i = 0; i < n; i++) { if(!node[i].flag) { printf("NO\n"); yes = false; break; } } if(yes) printf("YES\n"); } } return 0; }
习题5-7
方法一:直接用数组模拟一个队列
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 模拟一个队列即可 */ int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int T; scanf("%d", &T); while(T--) { int q[150]; int front = 0, rear = 0; int n, m, ans = 0; scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { int x; scanf("%d", &x); q[rear++] = x; } while(1) { int x = q[front]; bool flag = false; int i; for(i = (front + 1) % 150; i != rear; i = (i + 1) % 150) { if(q[i] > x) { flag = true; break; } } if(flag) { if(m == front) m = rear; front = (front + 1) % 150; q[rear] = x; rear = (rear + 1) % 150; } else { ans++; if(m == front) { printf("%d\n", ans); break; } front = (front + 1) % 150; } } } return 0; }
方法二:用优先队列
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<set> #include<string> #include<sstream> #include<cctype> #include<map> #include<stack> #include<queue> #include<cstdlib> #include<ctime> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; int gcd(int a, int b){return b==0?a:gcd(b,a%b);} /* 可以用优先队列存权值 */ struct node { int p; //权值 bool t; //是否是要求的 }; int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int T; scanf("%d", &T); while(T--) { int n, m, ans = 0; queue<node> q; priority_queue<int> pq; //普通的优先队列,从大到小排列,也可用数组存 scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { node x; scanf("%d", &x.p); if(i == m) x.t = true; else x.t = false; q.push(x); pq.push(x.p); } while(1) { node x = q.front(); int j = pq.top(); q.pop(); if(x.p == j) { ans++; pq.pop(); if(x.t) { printf("%d\n", ans); break; } } else { q.push(x); } } } return 0; }