• 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
    ");  
        else printf("Ashish
    ");  
    }
    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
    ");   
        else 
        {
            sort(b+1,b+1+n); 
            for(int i=1;i<=n;++i) if(a[i]!=b[i]) { printf("No
    "); return; }
            printf("Yes
    ");  
        }
    }
    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
    ",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
    ");  
        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
    "); 
            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
    "); 
                else printf("Yes
    ");   
            }
        }
        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
    ",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
    "); 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
    "); return;  }   
    	}        
    	printf("Yes
    ");  
    }
    int main() 
    { 
    	// setIO("input"); 
    	int T; 
    	scanf("%d",&T);  
    	while(T--) solve();  
    	return 0; 
    }
    

      

  • 相关阅读:
    final
    职场语句
    故事
    三个关键字
    关于重读字母去掉的代码
    Java书
    docker私库harbor的搭建
    配置允许匿名用户登录访问vsftpd服务,进行文档的上传下载、文档的新建删除等操作
    docker容器内外相互拷贝数据
    docker
  • 原文地址:https://www.cnblogs.com/guangheli/p/13073207.html
Copyright © 2020-2023  润新知