• Codeforces Round #644 (Div. 3)A->H(H为进制+reverse)


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

    题意:

    用最小正方形,容下两个相同矩形。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int a,b;
            cin>>a>>b;
            if(a>b)
                swap(a,b);
            if(a*2==b)
                cout<<b*b<<endl;
            else
            {
                if(2*a>b)
                    cout<<2*a*2*a<<endl;
                else
                    cout<<b*b<<endl;
            }
        }
    }

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

    题意:

    将n个数分成两组,要求一组的最大值减去另一组的最小值的绝对值最小。

    解析:

    直接sort然后找最小间距

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int maxn=1e3+10;
    int a[56];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            int minn=1e9;
            for(int i=1;i<=n;i++)
                cin>>a[i];
            sort(a+1,a+1+n);
            for(int i=2;i<=n;i++)
                minn=min(minn,a[i]-a[i-1]);
            cout<<minn<<endl;
        }
    }

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

    题意:

    给出n个数,要求进行两两配对,配对的两个数满足%2相等或者差值为1。

    问是否能把所有数配对成功。

    解析:

    题中已经表示:n为偶数,所以偶数的数目和奇数的数目的奇偶性是相同的。

    如果数目均为偶数,那么所有偶数内部配,奇数内部配,是可以包含所有数的。

    如果数目均为奇数,那么遍历一下,是否存在差值为1的两个数,如果有,一定为一奇一偶,数目中把它俩划掉,也是正好可以进行两两配对的。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int a[80];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            int j=0,o=0,d=0;
            for(int i=1;i<=n;i++)
                {
                    cin>>a[i];
                    if(a[i]%2!=0)
                        j++;
                    else
                        o++;
                }
            sort(a+1,a+1+n);
            for(int i=2;i<=n;i++)
            {
                if(a[i]-1==a[i-1])
                {
                    d++;
                }
            }
            if(j%2==0&&o%2==0)
                cout<<"YES"<<endl;
            else
            {
                if(d>0)
                    cout<<"YES"<<endl;
                else
                    cout<<"NO"<<endl;
            }
        }
    }

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

    题意:

    给出n和k,在[1,k]中找到一个x,使得n%x==0而且n/x最小。

    解析:

    直接遍历的话会超时。既然是找n的因子,那么直接在sqrt(n)以内找就可以了,复杂度为O(sqrt(n))。

    通过sqrt(n)左边因子来顺便判断右边

    找到的每一个因子,要满足<=k,并不断更新x的最大值,就能保证n/x最小。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    ll minn=1e9;
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            ll n,k;
            cin>>n>>k;
            minn=1e9;
            if(k>=n)
                cout<<"1"<<endl;
            else
            {
                ll maxx=0;
                for(ll i=1;i*i<=n;i++)
                {
                    if(n%i==0&&i<=k)
                    {
                        if(n/i<=k)
                            maxx=max(maxx,n/i);
                        maxx=max(maxx,i);
                    }
                }
                cout<<n/maxx<<endl;
            }
        }
    }

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

    题意:

    左边和上面发射炮弹,如果遇到阻碍,那么停住,标为1,而且上一个位置也标为1。给出一个情况,判定是否合法。

    解析:

    刚开始想复杂了,对于一个1来说,它的下方,要么是边界,要么是1,同理,它的右边也一样。

    所以如果一个1的下方和右方满足其中一个条件,就是合法的。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 60;
    char mp[maxn][maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            for(int i=0;i<n;i++)
                cin>>mp[i];
            int ok = 0;
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                {
                    if(i<n-1&&j<n-1&&mp[i][j]=='1')
                    {
                        if(mp[i+1][j]!='1'&&mp[i][j+1]!='1')
                            {
                                ok=1;break;
                            }
                    }
                }
            if(ok)
                cout<<"NO"<<endl;
            else
                cout<<"YES"<<endl;
        }
    }

    F:http://codeforces.com/contest/1360/problem/F

    题意:

    给出n个字符串,是否存在一个串,与这n个字符串最多只有一个位置不相同。

    解析:

    直接暴力模拟

    mp[1~n][1~m]记录每一个字符串。

    s[i]记录第一个字符串的每一位。

    以第一个字符串为基准,对它修改每一位,并check(),看是否合法:与其他字符串的不同位置数<=1

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 60;
    char mp[12][12];
    char s[12];
    int n , m ;
    bool check()
    {
        for(int i=1;i<n;i++)
        {
            int cnt=0;
            for(int j = 0 ; j  < m ; j++)
            {
                if(mp[i][j]!=s[j])
                    cnt++;
            }
            if(cnt>1)
                return false;
        }
        return true;
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            for(int i=0;i<n;i++)
                cin>>mp[i];
            for(int i=0;i<m;i++)
                s[i]=mp[0][i];
            int ok  = 1;
            for(int i=0;i<m;i++)
            {
                for(char j='a';j<='z';j++)
                {
                    s[i]=j;
                    if(check())
                    {
                        ok=0;
                        break;
                    }
                }
                if(!ok)
                    {
                    //    cout<<s<<"-"<<endl;
                        break;
                    }
                s[i]=mp[0][i];        //记得还原!因为每次只能修改一处
            }
    //        for(int i=0;i<m;i++)
    //            cout<<s[i];
    //            cout<<endl;
            s[m]='';
            if(ok)
                cout<<"-1"<<endl;
            else    
                cout<<s<<endl;
        }
    }

    G:http://codeforces.com/contest/1360/problem/G

    题意:

    是否存在一个n*m的矩阵,满足每行有a个1,每列有b个1。

    解析:

    如果一个位置变成了1,那么,它所在的行,列,都要+1。

    那么每次同时+1,就变成了n*a==m*b了。满足这个条件,才可以构造。

    构造的时候,肯定是尽量平均铺的。

    很明显,全扎堆在一起,行满足,列也未必满足。

    平均铺的代码:

                int id=0;
                for(int i=0;i<n;i++)
                {
                    for(int j=id;j<id+a;j++)
                        mp[i][j%m]=1;//%m防越界
                    id+=a;
                }

    记得初始化,否则样例都过不了:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=60;
    int mp[maxn][maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n , m , a , b;
            memset(mp,0,sizeof(mp));//初始化
            cin>>n>>m>>a>>b;
            if(n*a!=m*b)
                cout<<"NO"<<endl;
            else
            {
                int id=0;
                for(int i=0;i<n;i++)
                {
                    for(int j=id;j<id+a;j++)
                        mp[i][j%m]=1;
                    id+=a;
                }
                cout<<"YES"<<endl;
                for(int i=0;i<n;i++)
                {
                    for(int j=0;j<m;j++)
                        cout<<mp[i][j];
                    cout<<endl;
                }
            }
        }
    }

    H:http://codeforces.com/contest/1360/problem/H

    题意:

    2^m个只含0,1的串,删除掉n个所给串,求排序后处于中位数的那个串。

    解析:

    01串,其实就是个二进制,所以可以先把它们转化为十进制,也是符合字典序排序的。

    总串数为偶数:如果删除的数<中位数,那么中位数的位置要后移;

    总串数为奇数:如果删除的数>中位数,那么中位数的位置要前移。

    明确了这一点,那么就可以直接进行模拟了。

    用vector来储存需要删除的数,用map来标记是否被删除。

    逐一删除每一个串,每次求出未删除串中的中位数来。

    最后再转化为二进制,倒序输出

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int maxn=60;
    int mp[maxn][maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            vector<ll>v;
            ll n , m ;
            cin>>n>>m;
            string s;
            for(int i=1;i<=n;i++)
            {
                cin>>s;
                ll sum=0;
                for(int j=0;j<m;j++)
                    sum=sum*2+s[j]-'0';  //从前往后来转十进制
                v.push_back(sum);
            }
            ll all=1ll<<m;  //2^m
            ll md=(all-1)/2;
            map<ll,ll>mp;
            for(int i=0;i<n;i++)
            {
                mp[v[i]]=1;
                if(all%2==0)
                {
                    if(v[i]<=md)
                    {
                        md++;
                        while(mp[md])  //因为可能md已经被删除了。
                            md++;
                    }
                }
                else
                {
                    if(v[i]>=md)
                    {
                        md--;
                        while(mp[md])
                            md--;
                    }
                }
                all--;
            }
        //    cout<<md<<endl;
            string ch;
            for(int i=0;i<m;i++)  //转二进制操作
            {
                if(md>>i&1)
                    ch+='1';
                else
                    ch+='0';
            }
            reverse(ch.begin(),ch.end());  //倒序操作<algorithm>
            cout<<ch<<endl;
        }
    }

     记录一下两个容易混的知识点:

    右移 >>

    左移 <<

    左移几 就是乘以 2的几次方 左移三位 就是 乘以8
    右移几 就是除以 2的几次方

  • 相关阅读:
    Go开发环境搭建
    es入门小结
    Python操作ES
    mongodb
    RBAC-基于角色的访问控制 django缓存、信号、xadmin使用
    drf序列化群增、群改、群删
    drf过滤、分页、全局异常处理
    VS配置IISExpress外部IP访问
    Oracle中tnsping命令解析
    oracle导入Excel数据文件(大量数据)处理方法
  • 原文地址:https://www.cnblogs.com/liyexin/p/12968380.html
Copyright © 2020-2023  润新知