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

#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;
} 

猜你喜欢

转载自blog.csdn.net/qq_41093189/article/details/79532786