Meet in the middle

题目 POJ - 1903

AC代码

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<map>
#include<algorithm>
using namespace std;

const int maxn=1e5+5;
char s[30][30];
int a[30];
struct node{
    int x,id,cnt;
    bool operator <(const node &b)const{
        return x<b.x;
    }
}ans[maxn];

int solve(int x){
    int ans=0;
    for(int i=0;(1<<i)<=x;i++){
        if((x>>i)&1){
            ans^=a[i];
        }
    }
    return ans;
}

int cnt(int x){
    int ans=0;
    while(x){
        ans+=x&1;
        x>>=1;
    }
    return ans;
}

int main(){
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%s",s+i);
        int len=strlen(s[i]);
        for(int j=0;j<len;j++){
            a[i]|=1<<(s[i][j]-'A');
        }
    }
    if(n==1) {printf("0\n");return 0;}
    int mid=n>>1;
    int n1=1<<mid;
    for(int i=1;i<n1;i++){
        ans[i].x=solve(i);
        ans[i].id=i;
        ans[i].cnt=cnt(i);
    }
    sort(ans,ans+n1);
    int tmp=0,num=0;
    for(int i=0;i<n1&&ans[i].x==0;i++){
        if(ans[i].cnt>num){
            num=ans[i].cnt;
            tmp=ans[i].id;
        }
    }
    node k;
    for(int i=n1;i<(1<<n);i+=n1){
        k.x=solve(i);
        k.id=i;
        k.cnt=cnt(i);
        int pos=lower_bound(ans,ans+n1,k)-ans;
        for(int j=pos;j<n1&&ans[j].x==k.x;j++){
            if(ans[j].cnt+k.cnt>num){
                num=ans[j].cnt+k.cnt;
                tmp=ans[j].id|k.id;
            }
        }
    }
    cout<<num<<endl;
    for(int i=0;(1<<i)<=tmp;i++)if((tmp>>i)&1) cout<<i+1<<' ';
    return 0;
}

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页