您的位置:首页 > 其它

LA 2965 (map的正确使用方法+MEET IN THE MIDDLE)

2017-11-20 15:59 525 查看

Problem

给定N个大写字母组成的字符串,要求选择尽量多的串,使得每个大写字母出现偶数次

Data constraint

n <= 40

Solution

很显然中途相遇法

我们枚举前n/2个的状态,存在一个MAP里,然后再后n/2个直接查找

注意map的正确使用方法,我的理解是相当于一个hash,只不过代码短了. 当然还有几种用法,慢慢积累

map<int,int> table; //这就定义了一个map


table.count(x)表示x这个数字是否出现过

table[x]=y表示x这个位置赋值为y

int bitcount (int x){ return x==0 ? 0 : bitcount(x/2) + (x&1) ;}
再看看这个快速算1的个数的简便打法!!


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;

#define fo(i,a,b) for(i=a;i<=b;i++)

const int Maxn = 24;

map<int,int>table;

int n,i,j,a[Maxn];

char s[1000];

int bitcount (int x){ return x==0 ? 0 : bitcount(x/2) + (x&1) ;}

int main() {
scanf("%d",&n);

fo(i,0,n){
scanf("%s",s+1), a[i]=0;
for (j=1;s[j]!='\0';j++)
a[i] ^= (1<<(s[j]-'A'));
}

table.clear();

int n1=n/2, n2=n-n1;
fo(i,0,(1<<n1)-1){
int x=0;
fo(j,0,n1-1)
if (i & (1 << j)) x ^= a[j];
if (!table.count(x) || bitcount(table[x]) < bitcount(i)) table[x] = i;
}

int ans=0;
fo(i,0,(1<<n2)-1){
int x=0;
fo(j,0,n2-1)
if (i & (1 << j)) x ^= a[n1+j];
if (table.count(x) && bitcount(ans)<bitcount(table[x])+bitcount(i)) ans = (i << n1) + table[x];
}

printf("%d\n",bitcount(ans));

fo(i,0,n)
if (ans & (1<<i)) printf("%d ",i+1);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐