Codeforces Round #545 (Div. 2)

https://codeforces.com/contest/1138

B:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
string a,b;
void check(int x,int y,int z,int k)
{
    for(int i=0;a[i];i++)
    {
        if(a[i]=='1'&&b[i]=='0'&&x) //这里奇耻大辱,居然写反了 当时
        {
            cout<<i+1<<' ';
            x--;
        }
        if(a[i]=='0'&&b[i]=='1'&&y)
        {
            cout<<i+1<<' ';
            y--;
        }
        if(a[i]=='1'&&b[i]=='1'&&z)
        {
            cout<<i+1<<' ';
            z--;
        }
        if(a[i]=='0'&&b[i]=='0'&&k)
        {
            cout<<i+1<<' ';
            k--;
        }
    }

}
int main()
{
    int n;
    while(cin>>n)
    {

        cin>>a>>b;
        int x=0,y=0,z=0,k=0;

        for(int i=0;a[i];i++)
        {
            if(a[i]=='1'&&b[i]=='0') x++;
            if(a[i]=='0'&&b[i]=='1') y++;
            if(a[i]=='1'&&b[i]=='1') z++;
            if(a[i]=='0'&&b[i]=='0') k++;
        }
        int x1,x2,x3,x4 ,y1,y2,y3,y4;
        for(int i=0;i<=x;i++)
        {
            x1=i;
            y1=x-i;
            for(int j=0;j<=y;j++)
            {
                x2=j;
                y2=y-j;
                x3=y2-x1+z;
                y3=x1-y2+z;
                if(x3%2!=0||y3%2!=0||x3<0||y3<0) continue;
                x3/=2;
                y3/=2;
                x4=n/2-x1-x2-x3;
                y4=n/2-y1-y2-y3;
                if(x4+y4==k&&x4>=0&&y4>=0)
                {
                    cout<<"asd "<<x4<<' '<<y4<<endl;
//                    cout<<x1<<' '<<x2<<' '<<x3<<' '<<x4<<endl;
//                   cout<<y1<<' '<<y2<<' '<<y3<<' '<<y4<<endl;
                    check(x1,x2,x3,x4);
                    return 0;
                }
            }
        }

        cout<<-1<<endl;
    }






}

https://codeforces.com/contest/1138/problem/C

题意:
注意一点,是去寻找这一行,和这一列,行和列是单独的。
比如例子中,是因为横行确定为3了之后,所以上面的20才是4,4和 3所在和横行没有关系。

读题也是实力的一部分

题解;
对每一行每一列进行离散化。
然后,取行列的最大值,和行列数所在行列大小的差值和其对应的行列加起来的值的最大值进行比较。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 5;
struct node
{
    node ( int xx, int yy, int zz )
    {
        x = xx;
        y = yy;
        v = zz;
    }

    int x;
    int y;
    int v;
    int m;

};
vector<node > d[maxn];
bool cmp1 ( node a, node b )
{
    return a.x < b.x;
}

bool cmp2 ( node a, node b )
{
    return  a.v < b.v;
}

int hang[maxn], lie[maxn];

int main()
{
    int n, m;
    while ( cin >> n >> m )
    {
        int x;
        for ( int i = 1; i <= n; i++ )
        {
            for ( int j = 0; j < m; j++ )
            {
                // cin>>x;
                scanf ( "%d", &x );
                d[i].push_back ( node ( x, 0, j ) );
            }

            sort ( d[i].begin(), d[i].end(), cmp1 );
            map<int, int > tag;
            int les = 0;
            for ( int j = 0; j < m; j++ )
            {
                if ( !tag[d[i][j].x] )
                {
                    tag[d[i][j].x] = 1;
                    les++;
                }
                d[i][j].y = les;
            }

            hang[i] = les;
            sort ( d[i].begin(), d[i].end(), cmp2 );
        }
        //  cout<<" asd  "<<endl;
        for ( int i = 0; i < m; i++ )
        {
            vector<node > temp;
            for ( int j = 1; j <= n; j++ )
            {
                temp.push_back ( node ( d[j][i].x, 0, j ) );
            }
            map<int, int > tag;
            int les = 0;
            sort ( temp.begin(), temp.end(), cmp1 );
            for ( int j = 0; j < n; j++ )
            {
                if ( !tag[temp[j].x] )
                {
                    tag[temp[j].x] = 1;
                    les++;
                }
                temp[j].m = les;
            }
            lie[i] = les;
            sort ( temp.begin(), temp.end(), cmp2 );

            for ( int j = 0; j < n; j++ )
                d[j + 1][i].m = temp[j].m;

        }


        for ( int i = 1; i <= n; i++ )
        {
            for ( int j = 0; j < m; j++ )
            {
                int a = max ( hang[i], lie[j] );
                int b = max ( d[i][j].y - d[i][j].m + lie[j], d[i][j].m - d[i][j].y + hang[i]  );
                cout << max (  a, b ) << ' ';
            }
            cout << endl;
        }
    }
}

题意:
构造一个kmp能查出来尽可能子串的串串。

题解:
找一个最大后缀,然后无限构造后缀;直到01不够用
最大的后缀,只需要看看kmp算法中next数组的最后一位是几,就可以了。
然后 对于next数组的位置,一直无限构造后缀,直到01不够用。

赛中突然就失忆了!!!
kmp突然就不会了 ,手突然就残了。

代码真漂亮啊 - -。。。。。。


#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
int nex[maxn];
void getnext ( string &b )
{
    memset ( nex, 0, sizeof ( nex ) );
    for ( int i = 1, j = 0; b[i]; i++ )
    {
        while ( b[i] != b[j] && j > 0 )
            j = nex[j - 1];
        if ( b[i] == b[j] )
            nex[i] = j + 1, j++;
    }
}
int main()
{
    string a, b;
    while ( cin >> a >> b )
    {
        getnext ( b );
        int x = 0, y = 0;
        for ( int i = 0; a[i]; i++ )
            a[i] == '0' ? x++ : y++;

        string temp;
        char c;
        int len = b.size();
        int num = nex[len - 1], xe = 0, ye = 0, z = 1;
        for ( int i = 0;; ++i ,i = i == len ? num : i)
        {
            if ( i < num && z )
                c = b[i];
            else
                c = b[i], z = 0;

            c == '0' ? ++xe : ++ye;
            if ( xe > x || ye > y )
                break;
            temp += c;
        }
        while ( xe < x )
            temp += '0', xe++;
        while ( ye < y )
            temp += '1', ye++;
        cout << temp << endl;
    }
}

https://codeforces.com/contest/1138/problem/F

在这里插入图片描述

使用龟兔赛跑算法列出s和2*s。

所以 最后的证明是,(m-x) 是圈长的倍数,那么,当点再走(m-x) 步 ,最后则一定相遇。

#include <bits/stdc++.h>
using namespace std;

int get()
{
    int t;
    cin>>t;
    string s;
    for( int i=0 ;i< t;i++)
    {
        cin>>s;
    }
    return t;
}

int main()
{
    while(1)
    {
        cout<<"next 0 1"<<endl;
        get();
        cout<<"next 0"<<endl;

        if( get() != 3 )
            break;
    }

    while(1)
    {
        cout<<"next 0 1 2 3 4 5 6 7 8 9 "<<endl;
        if(get()!=2) break;
    }
    cout<<"done"<<endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值