USACO 4.1 Cryptcowgraphy(DFS)

这个题 我看了题解的提示,把自己的代码弄的只过了8组。。。最后两组无解的情况,实在搜不出来了。

加了判字符串哈希的数组,就是为了搞最后两组数组的。。。终于水过了。。。

代码非常难看,Tire树,字符串哈希(找的别人的)。。。

View Code
/*

 ID: cuizhe

 LANG: C++

 TASK: cryptcow

*/

#include <cstdio>

#include <cstring>

#include <cmath>

#include <string>

#include <ctime>

using namespace std;

#define MOD 99997

char str[101],z;

int oo[240];

char aim[100] = "Begin the Escape execution at the Break of Dawn";

int tire[10000][30];

int t = 0;

int time1,time2;

int hash[MOD];

int elfhash(char * str) {



    unsigned int res = 0,g;

    while (*str)

    {

        res = (res << 4) + (*str++);

        g = res & 0xF0000000;

        if (g) res ^= g >> 24;

        res &= ~g;

    }

    return res % MOD;

}

int find(char *s)

{

    int root = 0,len,i;

    len = strlen(s);

    if(len == 0) return 1;

    for(i = 0; i < len; i ++)

    {

        if(!tire[root][oo[s[i]]])

        {

            return 0;

        }

        root = tire[root][oo[s[i]]];

    }

    return 1;

}

void build(char *s)

{

    int i,len,root;

    len = strlen(s);

    root = 0;

    for(i = 0; i < len; i ++)

    {

        if(!tire[root][oo[s[i]]])

        {

            tire[root][oo[s[i]]] = t ++;

            root = t;

        }

        else

        {

            root = tire[root][oo[s[i]]];

        }

    }

}

void dfs(int step)

{

    int i,len,j,k,u,v,flag;

    char s[101];

    char temp[101];

    int qu1[10],qu2[10],qu3[10];

    int f1,f2,f3;

    f1 = f2 = f3 = 0;

    if(strcmp(str,aim) == 0)

    {

        z = 1;

        return ;

    }

    if(step == 0)

        return ;

    int kk;

    if(hash[kk = elfhash(str)] < 3)

    hash[kk] ++;

    else

    return ;

    strcpy(temp,str);

    if(z) return ;

    len = strlen(str);

    flag = 0;

    for(i = 0; i < len; i ++)

    {

        if(str[i] == 'C')

        {

            s[flag] = '\0';

            if(!find(s))

            {

                return;

            }

            qu1[f1++] = i;

            flag = 0;

        }

        else if(str[i] == 'O')

        {

            s[flag] = '\0';

            if(!find(s))

            {

                return;

            }

            if(f1 == 0) return;

            qu2[f2++] = i;

            flag = 0;

        }

        else if(str[i] == 'W')

        {

            s[flag] = '\0';

            if(!find(s))

            {

                return;

            }

            if(f1 == 0) return;

            qu3[f3++] = i;

            flag = 0;

        }

        else

        {

            s[flag ++] = str[i];

        }

    }

    for(i = 0; i < qu1[0]; i ++)

    {

        if(aim[i] != str[i])

            return ;

    }

    for(j = 0; j < f2; j ++)

    {

        for(i = 0; i < f1; i ++)

        {

            for(k = f3-1; k >= 0; k --)

            {

                if(qu1[i] < qu2[j] &&qu2[j] < qu3[k])

                {

                    for(u = qu1[i],v = qu2[j]+1; v < qu3[k]; u ++,v ++)

                    {

                        str[u] = temp[v];

                    }

                    for(v = qu1[i]+1; v < qu2[j]; v ++,u ++)

                    {

                        str[u] = temp[v];

                    }

                    for(v = qu3[k]+1; v < len; v ++,u ++)

                    {

                        str[u] = temp[v];

                    }

                    str[u] = '\0';

                    dfs(step-1);

                    strcpy(str,temp);

                }

            }

        }

    }

}

int main()

{

    char s[101];

    char ch[101];



    int len,i,j,k,num = 0;

    int c,o,w;

    c = o = w = 0;

    z = 0;

    freopen("cryptcow.in","r",stdin);

    freopen("cryptcow.out","w",stdout);

    len = strlen(aim);

    for(i = 0; i < len; i ++)

    {

        if(!oo[aim[i]])

            oo[aim[i]] = num ++;

    }

    for(i = 0; i < len; i ++)

    {

        for(j = i; j < len; j ++)

        {

            for(k = i; k <= j; k ++)

            {

                ch[k-i] = aim[k];

            }

            ch[k-i] = '\0';

            build(ch);

        }

    }

    i = 0;

    while(scanf("%c",&s[i])!=EOF)

    {

        if(s[i] == '\n')

        {

            len = i;

            break;

        }

        i ++;

    }

    s[i] = '\0';

    len = i;

    for(i = 0; i < len; i ++)

    {

        if(s[i] == 'C')

            c ++;

        else if(s[i] == 'O')

            o ++;

        else if(s[i] == 'W')

            w ++;

    }

    strcpy(str,s);

    if(c == o&&o == w)

    {

        dfs(c);

        if(z)

            printf("1 %d\n",c);

        else

            printf("0 0\n");

    }

    else

        printf("0 0\n");

    return 0;

}

 

你可能感兴趣的:(USACO)