Codeforces_797
学了一学期还是那么菜。
好久没更新,还是得放点东西的。
A.贪心最小的素因子,k = 1时,直接输出n就可以了。
#include<bits/stdc++.h> using namespace std; int n,k; vector <int> ans; int main() { ios::sync_with_stdio(false); cin >> n >> k; int cnt = 0; if(k == 1) { cout << n <<endl; return 0; } for(int i = 2;i <= n;i++) { while(n%i == 0) { ans.push_back(i); n /= i; cnt++; if(cnt == k-1 && n > 1 || cnt == k && n == 1) { for(int j = 0;j < ans.size();j++) cout << ans[j] << " "; if(n > 1) cout << n; return 0; } } } cout << -1 << endl; return 0; }
B.偶数大于0的全加,奇数排序一下,贪心最大的奇数个数的奇数和。
#include<bits/stdc++.h> using namespace std; int n,a[100005]; int main() { ios::sync_with_stdio(false); cin >> n; long long ans = 0; int cnt = 0; for(int i = 1;i <= n;i++) { int x; cin >> x; if(x%2 == 0 && x > 0) ans += x; else if(x%2) a[++cnt] = x; } sort(a+1,a+1+cnt); ans += a[cnt]; for(int i = cnt-1;i >= 1;i -= 2) { if(i-1 < 1) break; if(a[i]+a[i-1] > 0) ans += a[i]+a[i-1]; } cout << ans << endl; return 0; }
C.记录出现的字母,起始点为字符串首s,每次操作选下一个出现过的最小的字符c,终点为最后一个该字符的位置e,若s<e,则将该段的字符一个个入栈(等于c的字符直接输出)。另外,每次选取一个字符时,栈顶比当前字符小或相等的字符要输出。
#include<bits/stdc++.h> using namespace std; string s; int ok[128] = {0}; stack<char> ss; int main() { ios::sync_with_stdio(false); cin >> s; for(int i = 0;i < s.length();i++) ok[s[i]] = 1; int now = 0; for(char i = 'a';i <= 'z';i++) { if(!ok[i]) continue; while(!ss.empty() && ss.top() <= i) { cout << ss.top(); ss.pop(); } int t = s.length()-1; while(s[t] != i) t--; while(now <= t) { if(s[now] == i) cout << i; else ss.push(s[now]); now++; } } while(!ss.empty()) { cout << ss.top(); ss.pop(); } cout << endl; return 0; }
D.map记录每个数及个数,dfs判断点,每次更新判断区间,若符合,则当前点的值对应的value置为0,最后把每个值的value加起来就可以了。代码写麻烦了,不必要建树的。
#include<bits/stdc++.h> using namespace std; int n,a[100005],l[100005],r[100005],vis[100005] = {0}; map<int,int> mp; struct xx { int x; xx():l(NULL),r(NULL){}; xx *l,*r; }*root; void insertt(int now,xx *&p) { p = new xx; p->x = a[now]; if(l[now] > 0) insertt(l[now],p->l); if(r[now] > 0) insertt(r[now],p->r); } void dfs(xx *p,int ll,int rr) { if(!p) return; if(ll < p->x && p->x < rr) mp[p->x] = 0; dfs(p->l,ll,min(p->x,rr)); dfs(p->r,max(p->x,ll),rr); } int main() { ios::sync_with_stdio(false); cin >> n; for(int i = 1;i <= n;i++) { cin >> a[i] >> l[i] >> r[i]; if(l[i] > 0) vis[l[i]] = 1; if(r[i] > 0) vis[r[i]] = 1; mp[a[i]]++; } root = NULL; for(int i = 1;i <= n;i++) { if(vis[i]) continue; insertt(i,root); } dfs(root,-2e9,2e9); int ans = 0; for(map<int,int>::iterator it = mp.begin();it != mp.end();it++) ans += it->second; cout << ans << endl; return 0; }
E.将k分类,k>sqrt(n)时,直接暴力,O(sqrt(n))。其余的k,dp保存答案。
#include<bits/stdc++.h> using namespace std; int n,q,a[100005],dp[100005][355]; int main() { ios::sync_with_stdio(false); cin >> n; for(int i = 1;i <= n;i++) cin >> a[i]; for(int j = 1;j <= 350;j++) { for(int i = n;i >= 1;i--) { if(i+a[i]+j > n) dp[i][j] = 1; else dp[i][j] = dp[i+a[i]+j][j]+1; } } cin >> q; while(q--) { int p,k; cin >> p >> k; if(k <= 350) cout << dp[p][k] << endl; else { int cnt = 0; while(p <= n) p = p+a[p]+k,cnt++; cout << cnt << endl; } } return 0; }