A. Add Odd or Subtract Even
Add an odd number or subtract an even number to x each time. Ask the minimum number of operations from X to y.
Analysis: just judge the parity of x and y and discuss it.
#include <bits/stdc++.h> using namespace std; int main(){ int t; cin>>t; while(t--){ int a,b;scanf("%d%d",&a,&b); if(a>b){ printf("%d\n",((a&1)^(b&1))+1); } else if(a<b)printf("%d\n",(!((a&1)^(b&1)))+1); else printf("0\n"); } }
B. WeirdSort
Given an array A and an array p, for any i, the number of positions pi and pi + 1 of array a can be exchanged. Ask if you can make a array non descending.
Analysis: through the p array to determine a number of connecting blocks, sort each connecting block, and then determine whether the a array is in order.
#include <bits/stdc++.h> using namespace std; int main(){ int t;cin>>t; while(t--){ int n,m;cin>>n>>m; vector<int>a(n+1),p(m+1); for (int i = 1; i <= n; ++i) { scanf("%d",&a[i]); } for (int i = 1; i <= m; ++i) { scanf("%d",&p[i]); } sort(p.begin()+1,p.end()); p.erase(unique(p.begin()+1,p.end()),p.end()); int fro=p[1],bak=p[1]+1; for (int i = 2; i <= m; ++i) { if(p[i]!=p[i-1]+1){ sort(a.begin()+fro,a.begin()+bak+1); fro=p[i],bak=p[i]+1; } else bak=p[i]+1; } sort(a.begin()+fro,a.begin()+bak+1); bool ok = 1; for (int i = 2; i <= n; ++i) { if(a[i]<a[i-1])ok=0; } if(ok)puts("YES"); else puts("NO"); } }
C. Perform the Combo
Given a string s and an array p, for each pi, traverse the letters of 1-pi in s, and ask how many times each letter is traversed.
Analysis: differential.
#include <bits/stdc++.h> using namespace std; char s[200004]; int p[200004]; int a[200004]; int ans[26]; int main(){ int t; cin>>t; while(t--){ int n,m;scanf("%d%d",&n,&m); scanf("%s",s+1); for (int i = 0; i <= n; ++i) { a[i]=0; } for (int i = 0; i < 26; ++i) { ans[i]=0; } for (int i = 0; i < m; ++i) { scanf("%d",&p[i]); a[1]++,a[p[i]+1]--; } a[1]++; int sum = 0; for (int i = 1; i <= n; ++i) { sum+=a[i]; ans[s[i]-'a']+=sum; } for (int i = 0; i < 26; ++i) { printf("%d ",ans[i]); } puts(""); } }
D. Three Integers
Question meaning: given three numbers ABC, you can add + 1 or - 1 to any number each time. Ask at least several times to make A < = B < = C, and A is the factor of B, and B is the factor of C.
Analysis: violent enumeration, complexity is a harmonic series.
#include <bits/stdc++.h> using namespace std; int main() { int t; cin >> t; while (t--) { int a, b, c; cin >> a >> b >> c; int ans = 2e9,aa,bb,cc; for (int i = 1; i <= 2e4; ++i) { for (int j = i; j <= 2e4; j+=i) { for (int k = j; k <= 2e4; k+=j) { int temp = abs(a-i)+abs(b-j)+abs(c-k); if(temp<ans){ ans = temp; aa=i,bb=j,cc=k; } } } } cout<<ans<<endl; cout<<aa<<' '<<bb<<' '<<cc<<endl; } }
E. Construct the Binary Tree
Meaning: given n, D, construct a tree with n points and the sum of the depth of each store is d.
Analysis: it is easy to think that the upper bound of the sum of the depth of n points is a chain, and the lower bound is a complete binary tree.
Then you only need to calculate the number of points in each depth to get the final answer, and you can calculate the sum of a chain as (n-1) * n/2. Then you start to traverse from the deepest point, and every time you raise this point one level up, sum-1, you just need to keep putting the deepest point up to get a satisfactory answer.
#include <bits/stdc++.h> using namespace std; int dep[5004]; int ans[5004]; vector<int>v[5004]; int main(){ int t;cin>>t; while(t--){ int n,d;cin>>n>>d; for (int i = 0; i <= n; ++i) { v[i].clear(); } int up = 0,dw = (n-1)*n/2; int num = 0; for (int i = 1; num <= n; i<<=1) { num += i; if(num <= n){ up += log2(i)*i; } else { up += log2(i)*(i - num + n); } } // printf("%d %d\n",up,dw); if(d < up || d > dw){ puts("NO"); continue; } puts("YES"); memset(dep,0, sizeof(dep)); for (int i = 0; i < n; ++i) { dep[i]=1; } int now = dw,top = 1,pos = n-1; while(now > d){ int nxt = max(pos - now + d,top); now -= pos - nxt; dep[pos]--; dep[nxt]++; pos --; if(dep[top] == dep[top-1]*2)top++; } int cnt = 2; v[0].push_back(1); for (int i = 1; dep[i] ; ++i) { for (int j = 1; j <= dep[i]; ++j) { ans[cnt]=v[i-1][(j-1)/2]; v[i].push_back(cnt++); } } for (int i = 2; i <= n; ++i) { printf("%d ",ans[i]); } puts(""); } }
F. Moving Points
Problem meaning: n points, each point has a pos and a speed, D(U,V) is the minimum distance between two points of UV, find sum D(U,V).
Analysis: for any two points, if the two attributes of one point are greater than the other, its contribution is abs(pos1-pos2).
For one-dimensional sorting, the other one-dimensional bit maintenance statistics sum contribution is enough.
#include <bits/stdc++.h> using namespace std; struct BIT { int n; vector<long long> v; BIT(int n) : n(n) { v.resize(n + 1); } void update(long long x, long long d) { while (x <= n) { v[x] += d; x += (x & -x); } } long long que(long long x) { long long res = 0; while (x > 0) { res += v[x]; x -= (x & -x); } return res; } }; BIT bit(200004),num(200004); pair<int, int> p[200004]; unordered_map<int, int> mp; int main() { int n; cin >> n; vector<int> v; for (int i = 1; i <= n; ++i) { scanf("%d", &p[i].first); } for (int i = 1; i <= n; ++i) { scanf("%d", &p[i].second); v.push_back(p[i].second); } sort(v.begin(),v.end()); v.erase(unique(v.begin(), v.end()), v.end()); for (int i = 0; i < v.size(); ++i) { mp[v[i]] = i + 1; } sort(p + 1, p + n + 1); long long ans = 0; for (int i = n; i >= 1; --i) { ans += bit.que(mp[v[v.size()-1]]) - bit.que(mp[p[i].second]-1) - (num.que(mp[v[v.size()-1]]) - num.que(mp[p[i].second]-1))*(long long)(p[i].first - p[1].first); bit.update(mp[p[i].second],p[i].first - p[1].first); num.update(mp[p[i].second],1); } cout<<ans<<endl; }