HDU 2258 Continuous Same Game (1)[模拟]

  Continuous Same Game (2)是个很BT的搜索,这题是为了做(2)才来做一下的。其实直接模拟很easy的,纯属无聊写了个位运算版本的,感觉效率似乎差不多。。就是用3位表示每一位的状态,这样一个longlong就可以存下一列的状态。

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 typedef long long LL;
 5 LL d[22],nfull[22],full[22];
 6 int di[]={-1,1,0,0},dj[]={0,0,1,-1},ds[]={-3,3,0,0},vis[22];
 7 char str[22];
 8 int n,m,can,bi,bj,bans,scr;
 9 int canmove(int i,int j,int c){
10     return i>=0&&j>=0&&i<n&&j<m&&(c||0==((vis[j]>>i)&1));
11 }
12 int dfs(int i,int j,LL stat,int c){
13     if((d[j]&nfull[i])^stat)return 0;
14     int now=1;vis[j]|=(1<<i);
15     if(c)d[j]|=nfull[i];
16     for(int k=0;k<4;k++)
17         if(canmove(i+di[k],j+dj[k],c))
18             now+=dfs(i+di[k],j+dj[k],k?(stat<<ds[k]):(stat>>3),c);
19     return now;
20 }
21 void clear(){
22     for(int j=0,k=0;j<m;j++){
23         for(int i=0,now=0;i<n;i++){
24             LL stat=d[j]&nfull[now];
25             if(stat==nfull[now])d[j]=((d[j]&full[now])|((d[j]&~full[now+1])>>3));
26             else if(stat==0)break;
27             else now++;
28         }
29         if(d[j]!=0){
30             d[k++]=d[j];
31             if(k!=j+1)d[j]=0;
32         }
33     }
34 }
35 void init(){
36     for(int i=0;i<20;i++)nfull[i]=(7LL<<(3*i));
37     for(int i=0;i<20;i++)full[i]=(1LL<<(3*i))-1;
38 }
39 int main(){
40     //freopen("test.in","r",stdin);
41     init();
42     while(scanf("%d%d",&n,&m)!=EOF){
43         memset(d,0,sizeof d);
44         for(int i=n-1;i>=0;i--){
45             scanf("%s",str);
46             for(int j=0;j<m;j++)d[j]|=((LL)(str[j]-'0')<<(3*i));
47         }
48         can=1,scr=0;
49         for(;;){
50             bans=0;
51             memset(vis,0,sizeof vis);
52             for(int i=n-1;i>=0;i--)for(int j=0;j<m;j++)
53                 if(((vis[j]>>i)&1)==0&&(d[j]&nfull[i])&&((d[j]&nfull[i])!=nfull[i])){
54                     int tmp=dfs(i,j,d[j]&nfull[i],0);
55                     if(tmp>bans)bans=tmp,bi=i,bj=j;
56 
57                 }
58             if(bans<=1)break;
59             scr+=bans*(bans-1);
60             dfs(bi,bj,d[bj]&nfull[bi],1);
61             clear();
62         }
63         printf("%d\n",scr);
64     }
65 }

 

posted @ 2012-08-30 14:00  Burn_E  阅读(235)  评论(1编辑  收藏  举报