Codeforces 1138B Circus (构造方程+暴力)

题意:

给你两个01串,要你选n/2个位置,使得选的位置在s1中"1"的数量等于未选的s2中"1"的数量

n<=5000,1s

思路:

设两个串中出现"00""01""10""11"的总数是A,B,C,D,我们选的个数分别是a,b,c,d

数据最多能承受n^2的暴力

根据题意,有a+b+c+d=n/2     ①

c+d=B-b+D-d    ②

联立得d=B+D+a-n/2

于是我们暴力a,可以得到d

然后将a,d带入①可得b+c=n/2-a-d

暴力b可得c

最后只要a,b,c,d是否全部合法,输出方案即可

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>
#include<cmath>
    
#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
//#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) 

using namespace std;

typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;

const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 2e6+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;


int n;
char s1[maxn];
char s2[maxn];
int A,a,B,b,C,c,D,d;
int main(){
    scanf("%d", &n);
    scanf("%s", s1+1);
    scanf("%s", s2+1);
    for(int i = 1; i <= n; i++){
        if(s1[i]=='0'){
            if((s2[i]=='0'))A++;
            else B++;
        }
        else{
            if(s2[i]=='0')C++;
            else D++;
        }
    }
    int mm = min(A, n/2);
    a = b = c = d = -1;
    int ys = 0;
    for(a = 0; a <= A && a <= n/2; a++){
        if(B+D-n/2+a<=D&&B+D-n/2+a>=0){
            d = B+D-n/2+a;
            //int m = min(min(n/2-a-d,B),n/2);
            //printf("%d %d
",a,d);
            for(b = 0; b <= B&&b<=n/2-a-d; b++){
                //printf("  %d
",b);
                if(n/2-a-b-d<=C&&n/2-a-b-d>=0){
                    c = n/2-a-b-d;
                    ys=1;break;
                }
            }
            if(ys)break;
        }
    }
    //printf("%d %d %d %d
", a,b,c,d);
    if(!ys){
        return printf("-1"),0;
    }
    for(int i = 1; i <= n; i++){
        if(s1[i]=='0'){
            if(s2[i]=='0'&&a){
                a--;
                printf("%d ",i);
            }
            else if(s2[i]=='1'&&b){
                b--;
                printf("%d ",i);
            }
        }
        else if(s1[i]=='1'){
            if(s2[i]=='0'&&c){
                c--;
                printf("%d ",i);
            }
            else if(s2[i]=='1'&&d){
                d--;
                printf("%d ",i);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/10505395.html