A.winners总数为(k+1)diplomas。
#include<bits/stdc++.h> using namespace std; long long n,k; int main() { ios::sync_with_stdio(0); cin >> n >> k; long long t = n/2/(k+1); cout << t << " " << t*k << " " << n-t*(1+k) << endl; return 0; }
B.一步步确定每个a值,若冲突,则不存在。
#include<bits/stdc++.h> using namespace std; int n,m,a[105],ans[105] = {0}; map<int,int> used; int main() { ios::sync_with_stdio(0); cin >> n >> m; for(int i = 1;i <= m;i++) cin >> a[i]; for(int i = 2;i <= m;i++) { if(ans[a[i-1]]) { if((a[i-1]+ans[a[i-1]]-1)%n+1 != a[i]) { cout << -1 << endl; return 0; } } else { int t = a[i]-a[i-1]; if(t <= 0) t += n; if(used.count(t)) { cout << -1 << endl; return 0; } ans[a[i-1]] = t; used[t] = 1; } } int now = 1; for(int i = 1;i <= n;i++) { if(ans[i]) cout << ans[i] << " "; else { while(used.count(now)) now++; cout << now << " "; used[now] = 1; } } return 0; }
C.统计每个横坐标,纵坐标的4个方向的前缀后缀和,暴力比较每个沙发,注意减去自己。
#include<bits/stdc++.h> using namespace std; int d,n,m,ll,rr,tt,bb,x[100005],xx[100005],y[100005],yy[100005],l[100005] = {0},r[100005] = {0},t[100005] = {0},b[100005] = {0}; int main() { ios::sync_with_stdio(0); cin >> d >> n >> m; for(int i = 1;i <= d;i++) { cin >> x[i] >> y[i] >> xx[i] >> yy[i]; l[min(x[i],xx[i])]++; r[max(x[i],xx[i])]++; t[min(y[i],yy[i])]++; b[max(y[i],yy[i])]++; } cin >> ll >> rr >> tt >> bb; for(int i = 1;i <= max(n,m);i++) { l[i] += l[i-1]; t[i] += t[i-1]; } for(int i = max(n,m);i >= 1;i--) { r[i] += r[i+1]; b[i] += b[i+1]; } for(int i = 1;i <= d;i++) { int cntl = l[max(x[i],xx[i])-1]; int cntr = r[min(x[i],xx[i])+1]; int cntt = t[max(y[i],yy[i])-1]; int cntb = b[min(y[i],yy[i])+1]; if(x[i] != xx[i]) { cntl--; cntr--; } else { cntt--; cntb--; } if(cntl == ll && cntr == rr && cntt == tt && cntb == bb) { cout << i << endl; return 0; } } cout << -1 << endl; return 0; }
D.只要累加当前符合要求的颜色数量就可以了。
#include<bits/stdc++.h> using namespace std; int n,c,a[1000005] = {0}; int main() { ios::sync_with_stdio(0); cin >> n >> c; for(int i = 1;i <= n;i++) { int x; cin >> x; if(a[x] >= a[c]) a[x]++; } for(int i = 1;i <= 1000000;i++) { if(a[i] >= a[c] && i != c) { cout << i << endl; return 0; } } cout << -1 << endl; return 0; }
E.相乘整除一个数可以用相乘取模为0表示,从左往右找整除的一段,然后从右往左缩小这一段到最小,把两边的情况乘起来,因为一直重复这种操作会有重复的情况多计算了,所以每一次计算后更新首位置。
#include<bits/stdc++.h> using namespace std; int n,k,a[100005]; int main() { ios::sync_with_stdio(0); cin >> n >> k; for(int i = 1;i <= n;i++) cin >> a[i]; int b = 0; long long now = 1,ans = 0; for(int r = 1;r <= n;r++) { now = now*a[r]%k; if(!now) { int l = r+1; long long t = 1; while(--l) { t = t*a[l]%k; if(!t) break; now = t; } ans += (long long)(n-r+1)*(l-b); b = l; } } cout << ans << endl; return 0; }
F.n个点中,选k个组成一个连通图,其他n-k个连出去,因为n-k ≥ 连通图的边数,因此k个组成的连通图的边为。
最后答案为,二分确定k的临界,把临界点两边的两个点都算一下。
#include<bits/stdc++.h> using namespace std; int q; long long n; int main() { ios::sync_with_stdio(0); cin >> q; while(q--) { cin >> n; long long l = 0,r = n; while(l < r) { long long mid = (l+r+1)/2; if(n-mid < mid*(mid-1)/2) r = mid-1; else l = mid; } cout << max(n-l+l*(l-1)/2,n-(l+1)+n-(l+1)) << endl; } return 0; }