UVALive - 4856 OmniGravity(哈希+枚举)

题目:传送门

思路:题意是改变重力方向,四个方块移动的所有状态数量。就是简单的枚举,但是方块的移动以及状态的判断和存储比较繁琐。

下面是代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

const int MOD=1e6+13,N=10010;

struct point{
    int x,y;
};

int h[MOD],nexp[N],p=1;
string s[N];

int getHash(string x){
    int plus=255,ret=x[0],len=x.size();
    for(int i=1;i
        ret=(ret*plus)%MOD;
        ret+=x[i];
    }
    return ret%MOD;
}
bool insHash(string x){
    int c=getHash(x);
    for(int u=h[c];u;u=nexp[u]){
        if(s[u]==x)return 0;
    }
    nexp[p]=h[c],h[c]=p,s[p]=x,p++;
    return 1;
}

int cmp1(point a,point b)
{
    return a.x>b.x;
}
int cmp2(point a,point b)
{
    return a.y>b.y;
}
int cmp3(point a,point b)
{
    return a.x.x;
}
int cmp4(point a,point b)
{
    return a.y.y;
}

int dfs(string x,int nexd,point poi[4])
{
    int ans=1;
    string tmp;
    point pc[4];
    nexd=(nexd+2)%4;
    if(nexd!=0)//方块向下移
    {
        tmp=x;
        for(int i=0;i<4;i++)
            pc[i]=poi[i];
        sort(pc,pc+4,cmp1);
        for(int i=0;i<4;i++)
        {
            if(pc[i].x==6) continue;
            char ch=tmp[pc[i].x*8+pc[i].y];
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+1]='.';
            pc[i].x++;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+1]='.';
            pc[i].x++;
            while(tmp[pc[i].x*8+pc[i].y]=='.'&&tmp[pc[i].x*8+pc[i].y+1]=='.')
            {
                pc[i].x++;
                if(pc[i].x>=8) break;
            }
            pc[i].x--;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+1]=ch;
            pc[i].x--;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+1]=ch;
        }
        if(insHash(tmp))
        {
            //cout<;
            ans+=dfs(tmp,0,pc);
        }
    }
    if(nexd!=1)//方块向右移
    {
        tmp=x;
        for(int i=0;i<4;i++)
            pc[i]=poi[i];
        sort(pc,pc+4,cmp2);
        for(int i=0;i<4;i++)
        {
            if(pc[i].y==6) continue;
            char ch=tmp[pc[i].x*8+pc[i].y];
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+8]='.';
            pc[i].y++;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+8]='.';
            pc[i].y++;
            while(tmp[pc[i].x*8+pc[i].y]=='.'&&tmp[pc[i].x*8+pc[i].y+8]=='.')
            {
                pc[i].y++;
                if(pc[i].y>=8) break;
            }
            pc[i].y--;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+8]=ch;
            pc[i].y--;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+8]=ch;
        }
        if(insHash(tmp))
        {
            //cout<;
            ans+=dfs(tmp,1,pc);
        }
    }
    if(nexd!=2)//方块往上移
    {
        tmp=x;
        for(int i=0;i<4;i++)
            pc[i]=poi[i];
        sort(pc,pc+4,cmp3);
        for(int i=0;i<4;i++)
        {
            if(pc[i].x==0) continue;
            char ch=tmp[pc[i].x*8+pc[i].y];
            pc[i].x++;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+1]='.';
            pc[i].x--;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+1]='.';
            pc[i].x--;
            while(tmp[pc[i].x*8+pc[i].y]=='.'&&tmp[pc[i].x*8+pc[i].y+1]=='.')
            {
                pc[i].x--;
                if(pc[i].x<0) break;
            }
            pc[i].x++;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+1]=ch;
            pc[i].x++;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+1]=ch;
            pc[i].x--;
        }
        if(insHash(tmp))
        {
            //cout<;
            ans+=dfs(tmp,2,pc);
        }
    }
    if(nexd!=3)//方块向左移
    {
        tmp=x;
        for(int i=0;i<4;i++)
            pc[i]=poi[i];
        sort(pc,pc+4,cmp4);
        for(int i=0;i<4;i++)
        {
            if(pc[i].y==0) continue;
            char ch=tmp[pc[i].x*8+pc[i].y];
            //cout<;
            pc[i].y++;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+8]='.';
            pc[i].y--;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+8]='.';
            pc[i].y--;
            while(tmp[pc[i].x*8+pc[i].y]=='.'&&tmp[pc[i].x*8+pc[i].y+8]=='.')
            {
                pc[i].y--;
                if(pc[i].y<0) break;
            }
            pc[i].y++;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+8]=ch;
            pc[i].y++;
            tmp[pc[i].x*8+pc[i].y]=tmp[pc[i].x*8+pc[i].y+8]=ch;
            pc[i].y--;
            //cout<.x<<' '<.y<;
        }
        if(insHash(tmp))
        {
            //cout<;
            ans+=dfs(tmp,3,pc);
        }
    }
    return ans;
}

int main(){
    std::ios::sync_with_stdio(false); 
    int T;
    cin>>T;
    for(int t=1;t<=T;t++)
    {
        string mp,str;
        p=1;
        memset(h,0,sizeof(h));
        memset(nexp,0,sizeof(nexp));
        bool flag[4];
        memset(flag,0,sizeof(flag));
        point poi[4];
        for(int i=0;i<8;i++)
        {
            cin>>str;
            for(int j=0;j<8;j++)
            {
                if(str[j]>='A'&&str[j]<='D'&&!flag[str[j]-'A'])
                {
                    flag[str[j]-'A']=true;
                    poi[str[j]-'A'].x=i;
                    poi[str[j]-'A'].y=j;
                }
            }
            mp+=str;
        }
        printf("Case %d: %d\n",t,dfs(mp,-9,poi)-1);
        //cout<;
    }
}

你可能感兴趣的:(哈希,穷举)