C:
主要在于读题,然后贪心即可。最多的:剧毒打嘲讽,普通打圣盾。最少与最多情况相反。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[4008],b[48],c[48]; char s[4008]; int T,n; void solve(){ scanf("%d%d%d%d%d",&n,&b[1],&b[2],&b[3],&b[4]); scanf("%s",s); c[1] = b[1],c[2] = b[2],c[3] = b[3],c[4] = b[4]; int Max = 0,Min = 0; for(int i = 1;i <= n;i ++){ if(s[i - 1] == '1'){ if(b[3]) b[3] --,Max ++; else if(b[4]) b[4] --,b[3] ++; else if(b[1]) b[1] --,Max ++; else if(b[2]) b[2] --,b[1] ++; } else{ if(b[4]) b[4] --,b[3] ++; else if(b[3]) continue; else if(b[2]) b[2] --,b[1] ++; else continue; } } for(int i = 1;i <= n;i ++){ if(s[i - 1] == '1'){ if(c[4]) c[4] --,c[3] ++; else if(c[3]) c[3] --,Min ++; else if(c[2]) c[2] --,c[1] ++; else if(c[1]) Min ++,c[1] --; } else { if(c[3]) continue; else if(c[4]) c[4] --,c[3] ++; else if(c[1]) continue; else if(c[2]) c[2] --,c[1] ++; } } cout << Max << " " << Min << endl; return; } int main(){ cin >> T; while(T --) solve(); return 0; }
F:
有难度。既然正向考虑直接计数很难,那么反着考虑,如果总方案减去不合法方案数就是答案数。
某点连出的每一条黑边都可以与此点连出的每一条白边构成不合法三角环。设a[i] = 黑边数×百边数 , a[i]是此点贡献的不合法方案数。
由于每条边被调用2次,所以要除以2。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; ll a,b,c,p,d,n,ans; void solve(){ cin >> n >> a >> b >> c >> p >> d; ll ans = n * (n - 1) * (n - 2) / 6,t = 0; for(int i = 1;i <= n;i ++){ int x = 0,y = 0; for(int j = 1;j <= n;j ++) { if(i == j) continue; (a * (i + j) * (i + j) + b * (i - j) * (i - j) + c) % p > d ? x ++ : y ++; } t += x * y; } cout << ans - t / 2; return; } int main(){ solve(); return 0; }
K:
越大的数对答案贡献越大,那么越靠近数列中间,将其覆盖的区间越多。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; void solve(){ int n,t = 1,f = 0; cin >> n; f = n % 2 ? n - 1 : n; for(int i = 1;i <= n; i ++){ if(i <= n / 2){ printf("%d ",t); t += 2; } else if(n % 2 == 1 && i == n / 2 + 1){ printf("%d ",n); } else { printf("%d ",f); f -= 2; } } return; } int main(){ solve(); return 0; }
L:
bfs,注意判断马被卡的情况。第一发格式错误,是因为行末输出多余的空格。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int MAXN = 10001; char ma[201][201]; int ans[201][201]; int n,m,sx,sy; struct hh{ int x,y,cnt; }a[MAXN]; queue<hh>q; int X[] = {1,2,1,2,-1,-2,-1,-2}; int Y[] = {-2,-1,2,1,-2,-1,2,1}; bool pd(int x,int y){ if(x >= 1 && x <= n && y >= 1 && y <= m && ma[x][y] == '.' && ans[x][y] == -1) return true; return false; } bool pd_b(int X,int Y,int x,int y){ if(X == -2 && ma[x - 1][y] != 'X') return true; else if(X == 2 && ma[x + 1][y] != 'X') return true; else if(Y == -2 && ma[x][y - 1] != 'X') return true; else if(Y == 2 && ma[x][y + 1] != 'X') return true; else return false; } void bfs(){ q.push((hh){sx,sy,0}); ans[sx][sy] = 0; while(!q.empty()){ hh x = q.front(); q.pop(); for(int i = 0;i < 8;i ++){ int fx = X[i] + x.x; int fy = Y[i] + x.y; if(pd(fx,fy) && pd_b(X[i],Y[i],x.x,x.y)){ q.push((hh){fx,fy,x.cnt + 1}); ans[fx][fy] = x.cnt + 1; } } } return; } void solve(){ memset(ans,-1,sizeof(ans)); cin >> n >> m; for(int i = 1;i <= n;i ++) scanf("%s",ma[i] + 1); for(int i = 1;i <= n;i ++){ for(int j = 1;j <= m;j ++){ if(ma[i][j] == 'M') sx = i,sy = j; } } bfs(); for(int i = 1;i <= n;i ++){ for(int j = 1;j <= m;j ++){ printf("%d",ans[i][j]); if(j != m) printf(" "); } printf("\n"); } return; } int main(){ solve(); return 0; }
M:
这题说的不就是我吗2333。
注意有的选手可能ac某题后依然提交代码。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const ll M1 = 998244353; const ll M2 = 1000000; ll n,m,w; ll ans[20001]; ll ti[16]; struct hh{ ll cnt[12][3],num,jiao; }a[2001]; void solve(){ ll x,y,c; cin >> n >> m >> w; for(int i = 1;i <= w;i ++){ scanf("%lld%lld%lld",&x,&y,&c); a[x].jiao ++; if(c == 0){ a[x].cnt[y][0] ++; a[x].cnt[y][2]= max(a[x].cnt[y][2],a[x].cnt[y][0]); } else { a[x].cnt[y][1] ++; a[x].cnt[y][0] = 0; if(a[x].cnt[y][1] == 1){ ti[y] ++; a[x].num ++; } } } for(int i = 1;i <= n;i ++){ if(a[i].jiao == 0) ans[i] = M1; else if(a[i].num == 0) ans[i] = M2; else if(a[i].num == m) ans[i] = 0; else for(int j = 1;j <= m;j ++){ ans[i] += a[i].cnt[j][2] * a[i].cnt[j][2]; if(!a[i].cnt[j][1]){ ans[i] += a[i].cnt[j][2] * a[i].cnt[j][2]; if(ti[j]){ ans[i] += 20; if(ti[j] >= n / 2) ans[i] += 10; } } } } for(int i = 1;i <= n;i ++) printf("%lld\n",ans[i]); return; } int main(){ solve(); return 0; }