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; 
}

  

 

posted @ 2020-06-09 16:03  EM-LGH  阅读(137)  评论(0编辑  收藏  举报