您的位置:首页 > 其它

训练指南-1.3-高效算法-LA2965侏罗纪-中途相遇法,子集枚举,映射⭐⭐⭐⭐⭐难度:3

2018-03-12 20:58 363 查看
#include<cstdio>
#include<iostream>
#include<map>
using namespace std;
const int maxn=30;
int n,A[maxn];
char s[1000];
int bitcount(int x){
return x==0?0:bitcount(x/2)+(x&1);//x&1加括号
}

int main(){
while(cin>>n){
for(int i=0;i<n;i++){
cin>>s;
A[i]=0;
for(int j=0;s[j]!='\0';j++){
A[i]^=1<<(s[j]-'A');
}
}

int n1=n/2;
int n2=n-n1;

map<int,int> table;
table.clear();//注意初始化

for(int i=0;i<(1<<n1);i++){
int x=0;
for(int j=0;j<n1;j++){
if((1<<j)&i)
x^=A[j];
}
if(!table.count(x)||bitcount(table[x])<bitcount(i)) //table.countq前面不要丢掉!
table[x]=i;
}

int ans=0;
for(int i=0;i<(1<<n2);i++){
int x=0;
for(int j=0;j<n2;j++){
if((1<<j)&i)
x^=A[n1+j]; //n1+j不是n1+j-1
}
if(table.count(x)&&bitcount(ans)<bitcount(i)+bitcount(table[x]))
ans=(i<<n1)^table[x];//合并操作 需先将第二部分的结果左移n1位再和第一部分结果做^运算   是^运算不是&
}

cout<<bitcount(ans)<<endl;
for(int i=0;i<n;i++){
if((1<<i)&ans) cout<<i+1<<" ";
}
cout<<endl;
}
//system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: