题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=460&page=show_problem&problem=4072
题目大意:
给n个大写字母组成的字符串,选择尽量多的串,使得每个大写字母都能出现偶数次。
思路:
一看到Time limit: 18.000 seconds, 很high地无任何优化直接暴力写了一个,9s多过了,估计是自己有史以来耗时最久的一次AC
然后想着怎样优化一下,发现所有字母出现的次数可以用二进制来表示,0表示偶数,1表示奇数。这样的话,把所有选择的字符串状态进行抑或运算一次,结果为0就表示全部是偶数。
这样就从9s降到了1.692s
《竞赛指南》上介绍了效率更高的“中途相遇法”: 把字符串分为2部分, 首先计算前n/2个字符串的所有组合得到的XOR 值,保存在因设map中,然后在枚举后n/2个字符,找和前面一样的值。
// uva 1326 Jurassic Remains
// 直接位运算压缩
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cctype>
using namespace std;
int n;
char str[30];
int st[30];
bool vis[30];
int dfs(int cur, int cnt, int sta){
if(cur==n){
if(!sta) return cnt;
return -1;
}
if(cur<n){
vis[cur] = true;
int res = dfs(cur+1, cnt+1, sta^st[cur]);
if(res != -1) return res;
vis[cur] = false;
res = dfs(cur+1, cnt, sta);
if(res != -1) return res;
}
}
int main(){
while(~scanf("%d", &n)){
memset(st, 0, sizeof(st));
for(int i=0; i<n; ++i){
scanf("%s", str);
for(int j=0; str[j]; ++j){
st[i] ^= (1<<(str[j]-'A'));
}
}
memset(vis, 0, sizeof(vis));
printf("%d\n", dfs(0, 0, 0));
bool first=true;
for(int i=0; i<n; ++i)if(vis[i]){
first ? first=false : putchar(' ');
printf("%d", i+1);
}
putchar('\n');
}
return 0;
}
代码2:中途相遇法(递归版本):
#include<cstdio>
#include<cstring>
#include<map>
#include<iostream>
using namespace std;
const int MAXN = 30;
int n, vis;
int st[MAXN];
char str[MAXN];
map<int, int>table;
map<int, int>::iterator it;
int ansCnt, ansVis;
inline int bitCount(int x){
int cnt = 0;
while(x>0){
if(x&1) ++cnt;
x >>= 1;
}
return cnt;
}
void dfs1(int cur, int n, int vis, int sta){
it = table.find(sta);
if(it != table.end()){
if(bitCount(it->second) < bitCount(vis)){
it->second = vis;
}
}else{
table[sta] = vis;
}
if(cur < n){
dfs1(cur+1, n, vis|(1<<cur), sta^st[cur]);
dfs1(cur+1, n, vis, sta);
}
}
void dfs2(int cur, int n, int vis, int sta){
it = table.find(sta);
if(it != table.end()){
int cnt = bitCount(vis+it->second);
if(cnt > ansCnt){
ansCnt = cnt;
ansVis = vis+table[sta];
}
}
if(cur < n){
dfs2(cur+1, n, vis|(1<<cur),sta^st[cur]);
dfs2(cur+1, n, vis, sta);
}
}
int main(){
int i,j;
while(~scanf("%d", &n)){
memset(st, 0, sizeof(st));
table.clear();
for(i=0; i<n; ++i){
scanf("%s", str);
for(j=0; str[j]; ++j){
st[i] ^= (1<<(str[j]-'A'));
}
}
dfs1(0, (n>>1), 0, 0);
ansCnt=0, ansVis=0;
dfs2(n/2, n, 0, 0);
printf("%d\n", ansCnt);
bool first=true;
for(i=0; i<n; ++i)if((ansVis>>i)&1){
first ? first=false : putchar(' ');
printf("%d", i+1);
}
putchar('\n');
}
return 0;
}
版本3中途相遇法(直接枚举二进制的状态而不用递归):
#include<cstdio>
#include<cstring>
#include<map>
#include<iostream>
using namespace std;
const int MAXN = 30;
int n, vis;
int st[MAXN];
char str[MAXN];
map<int, int>table;
map<int, int>::iterator it;
int ansCnt, ansVis;
inline int bitCount(int x){
int cnt = 0;
while(x>0){ if(x&1) ++cnt;x >>= 1; }
return cnt;
}
int main(){
int i,j;
while(~scanf("%d%*c", &n)){
memset(st, 0, sizeof(st));
table.clear();
for(i=0; i<n; ++i){
gets(str);
for(j=0; str[j]; ++j){
st[i] ^= (1<<(str[j]-'A'));
}
}
// 枚举前n/2个所有组合状态
int end = (1<<(n>>1));
for(i=0; i<end; ++i){
int sta = 0;
for(j=0; j<(n>>1); ++j)if(i & (1<<j)){
sta ^= st[j];
}
it = table.find(sta);
if(it != table.end()){
if(bitCount(it->second) < bitCount(i)){
it->second = i;
}
}else{
table[sta] = i;
}
}
ansCnt=0, ansVis=0;
end = (1<<(n-n/2));
for(i=0; i<end; ++i){
int sta = 0;
for(j=(n>>1); j<n; ++j)if(i & (1<<(j-(n>>1)))){
sta ^= st[j];
}
it = table.find(sta);
if(it != table.end()){
int vis = i<<(n>>1);
int cnt = bitCount(vis+it->second);
if(cnt > ansCnt){
ansCnt = cnt;
ansVis = vis+it->second;
}
}
}
printf("%d\n", ansCnt);
bool first=true;
for(i=0; i<n; ++i)if((ansVis>>i)&1){
first ? first=false : putchar(' ');
printf("%d", i+1);
}
putchar('\n');
}
return 0;
}
分享到:
相关推荐
Jurassic
Jurassic库 c#后台执行js库,可子线程执行不需要ui线程
jurassic, 用于解析和执行JavaScript代码的.NET 库 什么是侏罗纪?Jurassic是ECMAScript语言和运行时的实现。 它旨在为. NET 提供最佳的性能和标准兼容的实现。 Jurassic不是面向最终用户的;而是打算集成到. NET ...
Jurassic Pack 1 2.2 与unity官方的模型差不多,有一丢丢差别
Jurassic Pack Vol I.rar
Hi! boys!Do you like to play game for cs?Yes?Oh!Free downlods the map,you can play games in the JURASSIC PARK!!!Please to free downlods NOW!
高二英语外研选修六 Module Jurassic ParkPPT课件.pptx
write a "C" program which estimates the probability that an explorer will safely escape from a dinosaur- and volcano-infested island ("Jurassic Island") by taking random walks across it. As well as ...
Jurassic Pack Vol. III Dinosaurs 侏罗纪包卷恐龙三Unity游戏模型资源unitypackage 版本2022 支持Unity版本2020.3.37或更高 侏罗纪包包含第三卷生物。 13 个游戏就绪的可玩生物,带有控制器、脚本和预制件。所有...
Jurassic Pack Vol. II Dinosaurs 侏罗纪包卷恐龙二号Unity游戏模型资源unitypackage 版本2022 支持Unity版本2020.3.37或更高 侏罗纪包包含第二卷生物。 13 个游戏就绪的可玩生物,带有控制器、脚本和预制件。所有...
侏罗纪世界进化新标签扩展为您的Chrome浏览器带来了新外观。 安装侏罗纪世界进化新标签页主题,并享受精选的侏罗纪世界进化高清图像。 它带有一些很酷的属性,这些属性可以改善您的“新标签页”体验,例如:-每个新...
语言:Bahasa Indonesia,Bahasa Melayu,Deutsch,English,Filipino,Français,Kiswahili,Nederlands,Norsk,Tiếng Việt,Türkçe,català,dansk,eesti,español,hrvatski,italiano,latviešu,lietuvių,magyar,polski...
带有高清侏罗纪世界堕落王国壁纸的新标签主题,专为侏罗纪世界堕落王国的恐龙迷制作。 侏罗纪世界堕落王国新标签-由FreeAddon提供安装我的侏罗纪世界堕落王国新标签页主题,每次您打开一个新标签页,即可享受侏罗纪...
Jurassic.pl:从Prolog调用Julia代码
#h1 jurassic-park此应用程序已开发为SpringBoot应用程序。 该应用程序的要求是 Grails-2.4.5 MySQL的 #h3数据库配置数据库配置可用于在'jurassic-park / grais-app / conf / config.groovy'文件中进行修改 在该...
We present coupled ocean-sea-ice simulations of the Middle Jurassic(~165 Ma)when Laurasia and Gondwana began drifting apart and gave rise to the formation of the Atlantic Ocean. Since the opening of ...
JavaScript引擎切换器 JavaScript引擎切换器确定用于访问流行JavaScript引擎( , , , , , , 和 )的基本功能的统一接口。 该库使您可以快速轻松地切换到使用另一个JavaScript引擎。 支持的.NET类型如下: ...
The important event in Jurassic tectonics in Mongolia was the subduction and closure of the Mongolia-Okhotsk ocean;correspondingly,basin evolution can be divided into two main stages,related to the ...