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;
}

 

posted @ 2013-11-04 16:23  cavehubiao  阅读(370)  评论(0编辑  收藏  举报