Cryptcowgraphy USACO 4.1(dfs搜索+剪枝)
题目越来越难了,我已经不抱希望自己能完全做出来了,先好好学习下大牛的题解吧。
这题我按照题解提示搜索+剪枝的,全部都用上了,还是在case 9 tle了,对比下大牛的代码,感觉自己的写还是太繁琐,
好多判断不需要或者完全可以归并到一种情况。
最后是跟着改改勉强过了
贴两个对比下。
1 /* 2 3 ID: hubiao cave 4 5 PROG: cryptcow 6 7 LANG: C++ 8 9 */ 10 11 12 13 14 #include<iostream> 15 #include<fstream> 16 #include<string> 17 #include<algorithm> 18 using namespace std; 19 20 int charcounter[256]; 21 int tempcounter[256]; 22 int code[3][200]; 23 int used[3][1000]; 24 25 bool elfhash[99991]; 26 27 int Ccnt,Ocnt,Wcnt,num; 28 string str,srcstr; 29 30 bool PreProcess(string&,string&); 31 bool dfs(int depth); 32 33 void deletecharAndSwap(int,int,int); 34 void addchar(int,int,int); 35 void update(); 36 unsigned int ELFhash(char*); 37 bool prefixCut(); 38 bool midCut(); 39 40 41 42 int main() 43 { 44 ifstream fin("cryptcow.in"); 45 ofstream fout("cryptcow.out"); 46 47 srcstr="Begin the Escape execution at the Break of Dawn"; 48 getline(fin,str); 49 50 if(str==srcstr) 51 { 52 fout<<1<<" "<<0<<endl; 53 return 0; 54 } 55 if(!PreProcess(str,srcstr)||Ccnt==0) 56 { 57 fout<<0<<" "<<0<<endl; 58 return 0; 59 } 60 num=Ccnt; 61 if(dfs(Ccnt)) 62 { 63 fout<<1<<" "<<num<<endl; 64 return 0; 65 } 66 else 67 { 68 fout<<0<<" "<<0<<endl; 69 return 0; 70 } 71 72 73 74 75 76 77 return 0; 78 79 80 } 81 82 83 bool PreProcess(string& str,string&srcstr) 84 { 85 86 if((str.length()-47)%3) 87 return false; 88 for(int i=0;i<srcstr.length();i++) 89 charcounter[srcstr[i]]++; 90 for(int i=0;i<str.length();i++) 91 { 92 char ch=str[i]; 93 if(ch=='C') 94 { 95 code[0][Ccnt++]=i; 96 continue; 97 } 98 if(ch=='O') 99 { 100 code[1][Ocnt++]=i; 101 continue; 102 } 103 if(ch=='W') 104 { 105 code[2][Wcnt++]=i; 106 continue; 107 } 108 tempcounter[ch]++; 109 } 110 for(int i=0;i<256;i++) 111 { 112 if(tempcounter[i]!=charcounter[i]) 113 return false; 114 } 115 if(Ccnt!=Ocnt||Ocnt!=Wcnt) 116 return false; 117 if(min(min(code[0][0],code[1][0]),code[2][0])!=code[0][0]) 118 return false; 119 if(max(max(code[0][Ccnt-1],code[1][Ocnt-1]),code[2][Wcnt-1])!=code[2][Wcnt-1]) 120 return false; 121 return true; 122 } 123 124 125 126 bool dfs(int depth) 127 { 128 unsigned int s=0; 129 if(elfhash[s=ELFhash(const_cast<char*>(str.c_str()))%99991]) 130 return false; 131 elfhash[s]=1; 132 if(!prefixCut()) 133 return false; 134 if(!midCut()) 135 return false; 136 if(depth==0) 137 { 138 if(str==srcstr) 139 return true; 140 else 141 return false; 142 } 143 for(int o=0;o<Ccnt;o++) 144 for(int w=Ccnt-1;w>=0;w--) 145 for(int c=0;c<Ccnt;c++) 146 { 147 //if(!used[0][c]&&!used[1][o]&&!used[2][w]&&code[0][c]<=code[1][o]&&code[1][o]<=code[2][w]) 148 if(code[0][c]<=code[1][o]&&code[1][o]<=code[2][w]) 149 { 150 //used[0][c]=used[1][o]=used[2][w]=1; 151 int cp=code[0][c],op=code[1][o],wp=code[2][w]; 152 //string lstr,rstr; 153 //lstr=str.substr(code[0][c]+1,code[1][o]-code[0][c]-1); 154 //rstr=str.substr(code[1][o]+1,code[2][w]-code[1][o]-1); 155 //if(lstr.length()==0||rstr.length()==0) 156 deletecharAndSwap(code[0][c],code[1][o],code[2][w]); 157 update(); 158 if(dfs(depth-1)) 159 return true; 160 //else 161 //{ 162 // unsigned int x=ELFhash(const_cast<char*>(str.c_str()))%99991; 163 //elfhash[x]=1; 164 //} 165 addchar(cp,op,wp); 166 update(); 167 //used[0][c]=used[1][o]=used[2][w]=0; 168 169 } 170 } 171 return false; 172 } 173 174 175 176 void deletecharAndSwap(int c,int o,int w) 177 { 178 string strsc,strco,strow,strwe; 179 strsc=str.substr(0,c); 180 strco=str.substr(c+1,o-c-1); 181 strow=str.substr(o+1,w-o-1); 182 strwe=str.substr(w+1,str.length()-w-1); 183 //str=strsc+strco+strow+strwe; 184 str=strsc+strow+strco+strwe; 185 } 186 void addchar(int c,int o,int w) 187 { 188 string strsc,strco,strow,strwe; 189 strsc=str.substr(0,c); 190 strsc+="C"; 191 strco=str.substr(c+w-o-1,o-c-1); 192 strco+="O"; 193 strow=str.substr(c,w-o-1); 194 strow+="W"; 195 strwe=str.substr(w-2,str.length()-w+2); 196 str=strsc+strco+strow+strwe; 197 198 } 199 200 void update() 201 { 202 Ccnt=Ocnt=Wcnt=0; 203 for(int i=0;i<str.length();i++) 204 { 205 if(str[i]=='C') 206 code[0][Ccnt++]=i; 207 if(str[i]=='O') 208 code[1][Ocnt++]=i; 209 if(str[i]=='W') 210 code[2][Wcnt++]=i; 211 } 212 } 213 214 unsigned int ELFhash(char*str) 215 { 216 unsigned int hash=0; 217 unsigned int x=0; 218 while(*str) 219 { 220 hash=(hash<<4)+(*str++); 221 if((x=hash&0xf0000000)!=0) 222 { 223 hash^=(x>>24); 224 hash&=~x; 225 } 226 } 227 return (hash&0x7fffffff); 228 } 229 230 bool prefixCut() 231 { 232 int cnt=0; 233 for(int i=0;i<str.length();i++) 234 { 235 if(str[i]!='C'&&str[i]!='O'&&str[i]!='W') 236 cnt++; 237 else 238 break; 239 } 240 if(str.substr(0,cnt)==srcstr.substr(0,cnt)) 241 return true; 242 else 243 return false; 244 } 245 246 bool midCut() 247 { 248 int marks[1000]; 249 int n=0; 250 string substr; 251 for(int i=0;i<Ccnt;i++) 252 { 253 marks[n++]=code[0][i]; 254 marks[n++]=code[1][i]; 255 marks[n++]=code[2][i]; 256 } 257 sort(marks,marks+n); 258 for(int i=0;i<n-1;i++) 259 { 260 substr=str.substr(marks[i]+1,marks[i+1]-marks[i]-1); 261 if(substr.length()==0) 262 continue; 263 if(srcstr.find(substr)==string::npos) 264 return false; 265 } 266 return true; 267 }
#include <iostream> #include <string> #include <algorithm> using namespace std; const int HashSize=131071; const string dest="Begin the Escape execution at the Break of Dawn"; bool searched[HashSize]; bool IsEncrypted(string text); int main() { freopen("cryptcow.in","r",stdin); freopen("cryptcow.out","w",stdout); string text; getline(cin,text); if (IsEncrypted(text)) { cout<<"1 "<<count(text.begin(),text.end(),'C')<<endl; } else { cout<<"0 0"<<endl; } return 0; } int Hash(const string &str); bool Impossible(const string &text); string Transform(const string &src,int c,int o,int w); bool IsEncrypted(string text) { int hash=Hash(text)%HashSize; if (searched[hash])//not reasonable, but works for most test data. { return false; } searched[hash]=true; if (text==dest) { return true; } if (Impossible(text)) { return false; } for (int o=1; o<text.length()-1; o++) { if (text[o]=='O') { for (int c=0; c<o; c++) { if (text[c]=='C') { for (int w=text.length()-1; w>o; w--) { if (text[w]=='W') { if (IsEncrypted(Transform(text,c,o,w))) { return true; } } } } } } } return false; } bool Impossible(const string &text) { if ((text.length()-dest.length())%3!=0) { return true; } int i=0,j; while (i<text.length()) { j=i+1; if (text[i]!='C' && text[i]!='O' && text[i]!='W') { while (j<text.length()) { if (text[j]=='C' || text[j]=='O' || text[j]=='W') { break; } j++; } if (dest.find(text.substr(i,j-i))==string::npos) { return true; } } i=j; } return false; } string Transform(const string &src,int c,int o,int w) { static char buffer[100]; int i,ich=0; for (i=0; i<c; i++) { buffer[ich++]=src[i]; } for (i=o+1; i<w; i++) { buffer[ich++]=src[i]; } for (i=c+1; i<o; i++) { buffer[ich++]=src[i]; } for (i=w+1; i<src.length(); i++) { buffer[ich++]=src[i]; } buffer[ich++]=0; return string(buffer); } int Hash(const string &str) { unsigned long h=0,g; for (int i=0; i<str.length(); i++) { h=(h<<4)+str[i]; g=h &0xf0000000l; if (g) { h^=g>>24; } h&=~g; } return h; }