zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    【转】【SEE】基于SSE指令集的程序设计简介
    【转】【Asp.Net】asp.net服务器控件创建
    ControlTemplate in WPF ——ScrollBar
    ControlTemplate in WPF —— Menu
    ControlTemplate in WPF —— Expander
    ControlTemplate in WPF —— TreeView
    ControlTemplate in WPF —— ListBox
    ControlTemplate in WPF —— ComboBox
    ControlTemplate in WPF —— TextBox
    ControlTemplate in WPF —— RadioButton
  • 原文地址:https://www.cnblogs.com/cavehubiao/p/3406837.html
Copyright © 2011-2022 走看看