题目:传送门
思路:题意是改变重力方向,四个方块移动的所有状态数量。就是简单的枚举,但是方块的移动以及状态的判断和存储比较繁琐。
下面是代码:
#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<;
}
}