zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    NET 获取实例所表示的日期是星期几
    NET npoi 保存文件
    快速排序
    JAVA poi 合并单元格
    JAVA poi 帮助类
    JAVA 字符串编码转换
    NET npoi 合并单元值处理
    NET npoi帮助类
    Task的暂停,继续,取消
    .net ref与out之间区别
  • 原文地址:https://www.cnblogs.com/swm8023/p/2663625.html
Copyright © 2011-2022 走看看