标签:
虽说是暴力题,但还是有很多很多的技巧与细节。
这题:
1、熟悉了位运算符,感觉异或操作的逼格有高了一级
2、可以用一个数的2进制来表示集合(这个需要多用)
3、中途相遇法。。。其实就是把总的集合拆成两半,降低指数使得暴力可解。(前段时间的中南校赛,好像也有个这种方法的题)
#include <cstdio> #include <map> using namespace std; const int maxn = 25; int a[maxn]; map<int,int>tab; int bitcnt(int x) { return x?bitcnt(x>>1)+(1&x):0; } int main() { // freopen("in.txt","r",stdin); int n; while(~scanf("%d",&n)) { char s[1005]; for(int i = 0;i<n;++i) { scanf("%s",s); a[i] = 0; for(int j = 0;s[j]!=0;++j)a[i]^=(1<<(s[j]-‘A‘)); } tab.clear(); int n1 = n/2,n2 = n-n1; for(int i = 0;i<(1<<n1);++i) { int x = 0; for(int j = 0;j<n1;++j)if(i&(1<<j))x^=a[j]; if(!tab.count(x) || bitcnt(tab[x])<bitcnt(i))tab[x] = i; } int ans = 0; for(int i = 0;i<(1<<n2);++i) { int x = 0; for(int j = 0;j<n2;++j)if(i&(1<<j))x^=a[j+n1]; if(tab.count(x) && bitcnt(ans)<bitcnt(tab[x])+bitcnt(i)) ans = tab[x]^(i<<n1); } printf("%d\n",bitcnt(ans)); for(int i = 0;i<n;++i)if(ans&(1<<i)) printf("%d ",i+1); puts(""); } return 0; }
标签:
原文地址:http://www.cnblogs.com/GJKACAC/p/4245897.html