hdu 4909 String(map)

来源:互联网 发布:如何挑选电视机知乎 编辑:程序博客网 时间:2024/06/05 11:36

hdu 4909 String

字母出现次数的奇偶关系,可以用状态压缩和位异或的形式表示。
由于数据范围是0~2^25,没法直接开数组,所以用到map容器
需要注意的是:如果仅仅只是为了查看map<key,value>中键是否存在,最好使用map::find(key)函数,直接用map[key]的值来判断会格外增加一倍的时间

#include <cstdio>#include <map>using namespace std;const int MAXN = 20005;int T, n, res, pos, z, k, o, p;int AA[30];char ss[MAXN];map<int,int> mp1, mp2;map<int,int>::iterator it;void solve(map<int,int> &mp, map<int,int> &mq){int i, j;for (it = mp.begin(); it!=mp.end();++it){z = it->second; k = it->first;for (i = 0; i<26; ++i){j = k^AA[i];if (mq.find(j) != mq.end())res += z*mq[j];}res += z*mq[k];}}int main()   {#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endiffor (int i = 0; i< 26; ++i) AA[i] = 1<<i;scanf("%d", &T);while (T--){scanf("%s", ss);mp1.clear(); mp2.clear();pos = -1;for ( n = 0; ss[n]; ++n)if (ss[n] == '?')pos = n;res = pos!=-1;p = 0;for (int i = pos-1; i>= 0; --i){o = ss[i]-'a';p = p^AA[o];if (!p) ++res;res += mp1[p];mp1[p]++;}p = 0;for (int i = pos+1; i< n; ++i){o = ss[i]-'a';p = p^AA[o];if (!p) ++res;res += mp2[p];mp2[p]++;}if (pos != -1){for (it = mp1.begin(); it!=mp1.end();++it){z = it->second; k = it->first;if (0 == (k & (k-1))) res += z;}for (it = mp2.begin(); it!=mp2.end();++it){z = it->second; k = it->first;if (0 == (k & (k-1))) res += z;}if (mp1.size() < mp2.size()) solve(mp1, mp2);else solve(mp2, mp1);}printf("%d\n", res);}    return 0;}


0 0