zoukankan      html  css  js  c++  java
  • Codeforces Round #648 (Div. 2)A-E(伪博弈+思维+暴力+BFS+思维/暴力/位运算)

    A:http://codeforces.com/contest/1365/problem/A

    题意:

    n*m的01矩阵,操作是把0变为1,条件是这个0所在的行列均无1。给出先手,求胜者。

    解析:

    改变一个0,那么它所在的行列均不能再使用。

    设不含1的列有x,不含1的行有y,那么min(x,y)即为可操作数。

    看下奇偶就行了。

    #include <cstdio>
    #include<cstring>
    #include<map>
    #include<iostream>
    using namespace std;
    const int maxn=60;
    int mp[maxn][maxn];
    int v[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n,m;
            cin>>n>>m;
            memset(mp,0,sizeof(mp));
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    cin>>mp[i][j];
            }
            int c1=0,c2=0;
            for(int i=1;i<=n;i++)
            {
                int sum=0;
                for(int j=1;j<=m;j++)
                    sum+=mp[i][j];
                if(sum==0)
                    c1++;
            }
            for(int j=1;j<=m;j++)
            {
                int sum=0;
                for(int i=1;i<=n;i++)
                {
                    sum+=mp[i][j];
                }
                if(sum==0)
                    c2++;
            }
            int md=min(c1,c2);
            if(md%2==0)
                cout<<"Vivek"<<endl;
            else
                cout<<"Ashish"<<endl;
        }
    }

    B:http://codeforces.com/contest/1365/problem/B

    题意:

    a[],b[](0/1)

    a[i]和a[j]交换条件是b[i]和b[j]不同,操作任意次

    问能否把a[]变成非递减序列

    解析:

    刚开始上去就写了个冒泡,其实不对,因为题目是可以进行任意的交换的。

    可以发现,只要b[]存在一对不同,那么就可以把a[]进行任意的摆放,一定可以把它变成非递减序列。

    当然先判断a[]本身是否为非递减序列

    #include <cstdio>
    #include<cstring>
    #include<map>
    #include<iostream>
    using namespace std;
    const int maxn=600;
    int a[maxn],b[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            for(int i=1;i<=n;i++)
                cin>>a[i];
            for(int i=1;i<=n;i++)
                cin>>b[i];
            int ok = 0,ok2=0;
            for(int i=1;i<n;i++)
            {
                if(a[i]>a[i+1])
                {
                    ok2=1;break;
                }
            }
            if(!ok2)
            {
                cout<<"Yes"<<endl;continue;
            }
            for(int i=1;i<n;i++)
            {
                if(b[i]!=b[i+1])
                {
                    ok=1;cout<<"Yes"<<endl;break;
                }
            }
            if(!ok)
                cout<<"No"<<endl;
        }
    }

    C:http://codeforces.com/contest/1365/problem/C

    题意:

    给出包含n个数的a[],b[]

    找出一个k,使任意数向右或左移动k个单位。求移动后的b[]能与a[]进行的最大匹配数(i==j&&a[i]==b[j])

    解析:

    因为是一个数移动,其他数都要动,所以

    统一向右移动即可

    暴力找一下每个数,在a[]的位置和在b[]的位置的差值dis,求出现最多的dis即可。

    比赛时交了一个919ms的,赛后进行了优化,但还是跑了700多秒

    #include <cstdio>
    #include<cstring>
    #include<map>
    #include<iostream>
    using namespace std;
    const int maxn=2e5+10;
    int a[maxn],b[maxn];
    int ds[maxn];
    int main()
    {
    
            int n;
            cin>>n;
            map<int,int>m1;
        //    map<int,int>m2;
            for(int i=1;i<=n;i++)
                cin>>a[i],m1[a[i]]=i;
            for(int i=1;i<=n;i++)
                cin>>b[i];
        //    map<int,int>m3;
            int maxx=0;
            for(int i=1;i<=n;i++)
            {
                int md;
                if(m1[b[i]]<i)
                    md=m1[b[i]]+n-i;
                else
                    md=m1[b[i]]-i;
                ds[md]++;    
                maxx=max(maxx,ds[md]);
            }
            
            cout<<maxx<<endl;
    }

    D:http://codeforces.com/contest/1365/problem/D

    题意:

    n*m的矩阵,包含:

    空:.

    墙:#

    好人:G

    坏人:B

    上下左右走动

    终点a[n][m]初始一定为空:'.'

    墙不能走,G,B处和 '.' 处可以走

    操作是把'.'变成墙'#',要求所有B不能到达终点,所有G可以到达终点,问是否能达到目的?

    解析:

    由于G,B处可以走,所以只要G,B出现相邻,那么如果此G能到达终点,B一定可以沿着G的路线到达终点,所以这个相邻情况一定是NO

    其他情况,

    先把B周围围死,再以终点为起点进行BFS,把终点能到达的位置全标记上。

    再次遍历全图,如果某个位置为G,但是没有被标记,说明它不能到达终点,为NO

    #include <cstdio>
    #include<cstring>
    #include<map>
    #include<queue>
    #include<iostream>
    using namespace std;
    const int maxn=100;
    char a[maxn][maxn];
    int vis[maxn][maxn];
    int dx[5]={0,0,-1,1};
    int dy[5]={-1,1,0,0};
    int n , m ;
    struct node{
        int x,y;
    };
    int ok = 0;
    void check(int x,int y)
    {
        for(int i=0;i<4;i++)
        {
            int ddx=x+dx[i];
            int ddy=y+dy[i];
            if(ddx>=1&&ddx<=n&&ddy>=1&&ddy<=m)
            {
                if(a[ddx][ddy]=='.')
                    a[ddx][ddy]='#';
                if(a[ddx][ddy]=='G')
                {
                    ok=1;break;
                }
            }
        }
    }
    void bfs(int n,int m)
    {
        queue<node>q;
        q.push((node){n,m});
        vis[n][m]=1;
        while(!q.empty())
        {
            node s=q.front();
            q.pop();
            for(int i=0;i<4;i++)
            {
                int ddx=s.x+dx[i];
                int ddy=s.y+dy[i];
                if(ddx>=1&&ddx<=n&&ddy<=m&&ddy>=1&&!vis[ddx][ddy])
                {
                    if(a[ddx][ddy]!='#')
                    {
                        vis[ddx][ddy]=1;
                        q.push((node){ddx,ddy});
                    }
                }
            }
        }
    }
    int main()
    {    
        int t;
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            memset(vis,0,sizeof(vis));
            ok=0;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    cin>>a[i][j];
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(a[i][j]=='B')
                    {
                        check(i,j);
                    }
                }
            }
            
            if(ok)
                {
                    cout<<"No"<<endl;continue;
                }
        //    a[n][m]='.';
            if(a[n][m]!='#')
            bfs(n,m);    
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(a[i][j]=='G'&&!vis[i][j])
                    {
                        ok=1;break;
                    }
                }
                if(ok)
                    break;
            }
            if(ok)
                cout<<"No"<<endl;
            else
                cout<<"Yes"<<endl;
        }
    }

    E:http://codeforces.com/contest/1365/problem/E

    题意:

    n个数的a[],

    从中选取k个数,对这k个数转成二进制,位置一一对应从上到下排起来

    如果某位置满足max(1,k-2)个1,sum就+2^i(i为第几位)

    求最大的sum

    解析:

    max(1,k-2),当k<=3时,取得是1。所以k取0,1,2,3时,只要符合条件位有一个1,就没问题。所以k只要小于4,不管取几,对答案都没有影响。

    当K>=4,max(1,k-2)=2,假设前3个数已经是最大解,那么加入第4个数,需要满足每位2个1才行,显然,求的sum可能会变小,没有必要。

    sum加的只是2^i,每位几个1,与它无关,只要有1,就可以。所以k>3,对sum的影响,要么不变,要么减小。

    所以只看k=3,就可以了

    n^3暴力遍历即可,注意long long

    这里用到了or: ' | ' 运算:只要有1,就是1。

    #include <cstdio>
    #include<cstring>
    #include<map>
    #include<queue>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    const int maxn=600;
    ll a[maxn];
    int main()
    {    
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        ll maxx=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                for(int k=1;k<=n;k++)
                    maxx=max(maxx,a[i]|a[j]|a[k]);
            }
        }
        cout<<maxx<<endl; 
    }
  • 相关阅读:
    安装JDK,如何配置PATH,如何配置CLASSPATH
    存储过程笔记
    用BeanFactoryAware接口,用BEAN的名称来获取BEAN对象
    静态工厂实例代码
    setTimeout 和 setInterval 的区别
    Spring Autowire自动装配
    动态工厂模式代码实例
    JS处理回车事件
    不错的Spring学习笔记(转)
    单例模式要点
  • 原文地址:https://www.cnblogs.com/liyexin/p/13067680.html
Copyright © 2011-2022 走看看