Codeforces Round #648 (Div. 2) (A-F)
这场比赛的题都偏水,比赛的时候切了 A ~ E
A Matrix Game
刚开始看错题了,以为是不能相邻,然后就不会了.
又读了一遍题,发现不能同行或同列,那就判断一下奇偶性就行了.
code:
#include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; int a[100][100]; void solve() { int n,m,X=0,Y=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { scanf("%d",&a[i][j]); } } for(int i=1;i<=n;++i) { int flag=0; for(int j=1;j<=m;++j) if(a[i][j]) flag=1; if(!flag) ++X; } for(int i=1;i<=m;++i) { int flag=0; for(int j=1;j<=n;++j) if(a[j][i]) flag=1; if(!flag) ++Y; } X=min(X,Y); if(X%2==0) printf("Vivek\n"); else printf("Ashish\n"); } int main() { // setIO("input"); int T; scanf("%d",&T); while(T--) solve(); return 0; }
B Trouble Sort
刚开始想了一个不知道有没有正确性的做法,反正一直 WA.
然后我就觉得这个 B 肯定不难,而且有结论,所以就猜如果有 0 和 1 就一定合法,然后就过了.
#include <bits/stdc++.h> #define N 507 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int a[N],b[N],c[N]; void solve() { int n,s1=0,s2=0; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i]; for(int i=1;i<=n;++i) { scanf("%d",&c[i]); if(c[i]==0) s1=1; if(c[i]==1) s2=1; } if(s1&&s2) printf("Yes\n"); else { sort(b+1,b+1+n); for(int i=1;i<=n;++i) if(a[i]!=b[i]) { printf("No\n"); return; } printf("Yes\n"); } } int main() { // setIO("input"); int T; scanf("%d",&T); while(T--) solve(); return 0; }
C Rotation Matching
刚开始看这个 C 的时候被卡住了,怎么都没有思路.
然后突然想到这种循环问题可以倍长,而且这道题是排列,所以直接按位置算贡献就好了.
#include <bits/stdc++.h> #define ll long long #define N 400008 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int a[N],b[N],pos[N],cnt[1000000]; int main() { //setIO("input"); int n; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); for(int i=1;i<=n;++i) scanf("%d",&b[i]),pos[b[i]]=i; for(int i=1;i<=n;++i) a[i+n]=a[i]; for(int i=1;i<=2*n;++i) { int x=pos[a[i]]; cnt[i-x+N]++; } int ans=0; for(int i=0;i<=n;++i) ans=max(ans,cnt[i+N]); printf("%d\n",ans); return 0; }
D Solve The Maze
显然,如果有黑和白挨着一定是不合法的.
然后最合适的策略一定是贴着黑色的轮廓把黑色给包围住.
所以就枚举黑色的格子,然后贪心地填充,最后跑一个 bfs 判一下连通性就行了.
#include <bits/stdc++.h> #define ll long long #define N 60 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int dx[]={-1,0,1,0}; int dy[]={0,-1,0,1}; char g[N][N]; int vis[N][N],col[N][N]; struct data { int y,x; data(int y=0,int x=0):y(y),x(x){} }; queue<data>q; void solve() { int n,m,cn=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%s",g[i]+1); for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { if(g[i][j]=='G') col[i][j]=1,++cn; else if(g[i][j]=='B') col[i][j]=2; else if(g[i][j]=='#') col[i][j]=3; } } if(cn==0) printf("Yes\n"); else { int flag=0; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { if(col[i][j]!=2) continue; for(int t=0;t<4;++t) { int y=i+dy[t],x=j+dx[t]; if(col[i][j]==2&&col[y][x]==1) { flag=1; break; } if(col[y][x]!=2) col[y][x]=3; } if(flag==1) break; } if(flag==1||col[n][m]==3) printf("No\n"); else { vis[n][m]=1; q.push(data(n,m)); while(!q.empty()) { data e=q.front(); q.pop(); for(int i=0;i<4;++i) { int x=e.x+dx[i],y=e.y+dy[i]; if(col[y][x]!=3&&!vis[y][x]&&x>=1&&x<=m&&y>=1&&y<=n) { vis[y][x]=1; q.push(data(y,x)); } } } int pp=0; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { if(col[i][j]==1&&!vis[i][j]) pp=1; } if(pp==1) printf("No\n"); else printf("Yes\n"); } } memset(col,0,sizeof(col)); memset(vis,0,sizeof(vis)); } int main() { // setIO("input"); int T; scanf("%d",&T); while(T--) { solve(); } return 0; }
E Maximum Subsequence Value
这道题要求出现次数大于等于区间长度减 2,必有高论,所以要找规律+归纳.
然后发现有用元素最多 3 个,所以 $O(n^3)$ 暴力枚举就行了.
#include <bits/stdc++.h> #define ll long long #define N 600 #define setIO(s) freopen(s".in","r",stdin) using namespace std; ll a[N]; int main() { // setIO("input"); int n; ll ans=0; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%lld",&a[i]),ans=max(ans,a[i]); for(int i=1;i<=n;++i) { for(int j=i+1;j<=n;++j) { ans=max(ans,a[i]|a[j]); for(int x=j+1;x<=n;++x) { ans=max(ans,a[i]|a[j]|a[x]); } } } printf("%lld\n",ans); return 0; }
F Swaps Again
比赛地时候没做出来 QAQ......
首先,如果 $n$ 为奇数,且 a 和 b 最中间元素不相等则一定无解.
然后我们手画几次后发现一个规律:对于初始地 $a$ 定义数对 $(a[i],a[n-i+1])$,然后我们发现不论怎样对 a 操作,这些数对依然不变,只是位置改变.
然后如果 a 能转换成 b,就要求 b 的所有数对必须和 a 的相等,然后我们发现如果满足这个条件的话 a 就一定能变成 b.
#include <bits/stdc++.h> #define N 509 #define ll long long #define P make_pair #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,a[N],b[N]; map<pair<int,int>,int>se; void solve() { int n,x,y,z; scanf("%d",&n),se.clear(); for(int i=1;i<=n;++i) scanf("%d",&a[i]); for(int i=1;i<=n;++i) scanf("%d",&b[i]); if((n&1)&&(a[n/2+1]!=b[n/2+1])) { printf("No\n"); return ; } for(int i=1;i<=n/2;++i) { x=a[i],y=a[n-i+1]; if(x>y) swap(x,y); se[P(x,y)]++; } for(int i=1;i<=n/2;++i) { x=b[i],y=b[n-i+1]; if(x>y) swap(x,y); if(se[P(x,y)]) --se[P(x,y)]; else { printf("No\n"); return; } } printf("Yes\n"); } int main() { // setIO("input"); int T; scanf("%d",&T); while(T--) solve(); return 0; }