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

 

posted @ 2013-03-01 13:28  Naix_x  阅读(265)  评论(0编辑  收藏  举报