https://codeforces.com/contest/1263
enmmmmmm 手速快是真的很有优势,
#include <bits/stdc++.h> //cf603 div2 using namespace std; #define _for(i,a,b) for(int i = (a); i < (b); i++) #define _rep(i,a,b) for(int i = (a); i <= (b); i++) #define ll long long void taskA(){// 可以证明当 最大数大于其他两数之和时, ans = 其他两数之和 // 否则 ans = (r+g+b)/2 可以用数学归纳法证明 //https://www.cometoj.com/contest/68/problem/B?problem_id=3934 有点像之前comet做的一道题,所以很快就A了 int t; cin >> t; while(t--) { int r,g,b; cin >> r >> g >> b; if(g < b) swap(g, b); if(r < g) swap(r, g); if(r >= g+b) cout << g+b << endl; else cout << (g+b+r)/2 << endl; }return; } void taskB(){// n <= 10 所以可以直接枚举就好, 用两个set存下已有的pin码, 如果修改后的没有冲突就加入答案 int t; cin >> t; while(t--) { int n; cin >> n; set<string> AA, BB; vector<string> ans; string s[12]; _for(i,0,n) { cin >> s[i]; AA.insert(s[i]); } int cnt1 = 0; _for(i,0,n) { if(!BB.count(s[i])) { ans.push_back(s[i]); BB.insert(s[i]); continue; } cnt1++; int f = 0; _for(j,0,4) { _for(k,0,10) { char c = '0'+k; swap(s[i][j], c); if(!BB.count(s[i]) && !AA.count(s[i])){ BB.insert(s[i]); ans.push_back(s[i]); f = 1; break; } swap(s[i][j], c); } if(f) break; } } cout << cnt1 << endl; _for(i,0,n) cout << ans[i] << "\n"; }return; } void taskC(){// 还是有些迷, 没看懂题 但是看样例猜到了是 i 1~sqrt(n), 答案为 n/i的 解 // 用个 set ,自动排序 从小到大 美滋滋 int t; cin >> t; while(t--) { int n; cin >> n; set<int> ans; int q = sqrt(n); //cout << "q = " << q << endl; _rep(i,0,q) ans.insert(i); _rep(i,1,q) ans.insert(n/i); cout << ans.size() << endl; for(auto it: ans) cout << it << " "; cout << endl; }return; } int main(){ ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); //freopen("output.txt", "w", stdout); //taskA(); //taskB(); //taskC(); return 0; }
C题 (看了卿学姐的视频)
还可以用二分查找,每次将 i (1~n) x=n/i 压入, 然后查找等于 x 的最大下标, 缩小空间 代码如下
#include <bits/stdc++.h> using namespace std; void solve(){ vector<int> Ans; int n; cin >> n; int x = 1; Ans.push_back(n); while(x <= n) { int l = x, r = n+1, ans = 1; int d = n/l; while(l <= r) { int mid = (l+r)/2; if(n/mid == d) l = mid+1, ans = mid; else r = mid-1; } Ans.push_back(n/(ans+1)); x = ans+1; } sort(Ans.begin(), Ans.end()); //Ans.erase(unique(Ans.begin(), Ans.end()), Ans.end()); cout << Ans.size() << endl; for(auto to : Ans) cout << to << " "; cout << endl; return; } int main(){ int t; cin >> t; while(t--) solve(); return 0; }
D题
// 有点像联想记忆, 如果两个字符串中有相同的字符 那 他们属于一个集合
// 遍历 问有几个集合, 可以用DSU 并查集 也可以用题解中的二维数组
#include<bits/stdc++.h> using namespace std; const int N = 2e5+100; vector<int> g[N]; vector<bool> used(N, 0); void dfs(int i){//e俄罗斯套娃 used[i] = 1; _for(j,0,g[i].size()) { if(!used[g[i][j]]) dfs(g[i][j]); }return; } void taskD(){ int t; //cin >> t; t = 1; while(t--) { int n; cin >> n; _for(i,0,n) { string s; cin >> s; _for(j,0,s.size()) { int a = i, b = s[j]-'a'+n;// +n 防止和前 n 个字符串下标冲突 g[a].push_back(b); g[b].push_back(a); } } int res = 0; //_for(i,n,n+26) { cout << used[i]?"1\n": "0\n"; } _for(i,n,n+26) { if(!used[i] && !g[i].empty()) { int f = 0; dfs(i); if(!f) res++; } } //_for(i,n,n+26) { cout << used[i]?"1\n": "0\n"; } if(n==1) res = 1; cout << res << endl; }return; } int main(){ taskD(); return 0; }