zoukankan      html  css  js  c++  java
  • Flood-it!

    Flood-it!

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4127/http://acm.split.hdu.edu.cn/showproblem.php?pid=4127

    IDA*

    这题题意有点不清,我去找了这个游戏玩了会才明白什么回事= =

    (游戏链接:http://unixpapa.com/floodit/?sz=26&nc=6

    刚开始我将状态压缩成2^64(用unsigned long long存储,当n=8全部都是一种颜色时用(unsigned long long)(-1)特判),用map去重,dfs判断每次互通的格子,A*是该状态下的颜色种类-1,一次次迭代加深,结果是TLE...

    代码如下:

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<set>
     5 #include<map>
     6 #include<cstring>
     7 #define N 8
     8 using namespace std;
     9 typedef unsigned long long LL;
    10 int mp[N][N],n,deep;
    11 bool vis[N][N],ok;
    12 map<LL,bool>state;
    13 int dx[]={-1,1,0,0};
    14 int dy[]={0,0,-1,1};
    15 LL dfs(int px,int py,int color,LL s){
    16     LL sta=s;
    17     vis[px][py]=1;
    18     for(int i=0;i<4;++i){
    19         int x=px+dx[i];
    20         int y=py+dy[i];
    21         if(0<=x&&x<n&&0<=y&&y<n)
    22         if(color==mp[x][y]||(sta&((LL)1<<(x*n+y)))>0)
    23         if(!vis[x][y]){
    24             sta|=((LL)1<<(x*n+y));
    25             sta|=dfs(x,y,color,sta);
    26         }
    27     }
    28     return sta;
    29 }
    30 LL init(){
    31     ok=0;
    32     state.clear();
    33     memset(vis,0,sizeof(vis));
    34     return dfs(0,0,mp[0][0],1);
    35 }
    36 int Astar(int color,LL s){
    37     set<int>st;
    38     st.insert(color);
    39     for(int i=0;i<n;++i)
    40     for(int j=0;j<n;++j)
    41     if((s&(1<<(i*n+j)))==0)
    42     if(st.count(mp[i][j])==0)
    43         st.insert(mp[i][j]);
    44     return (st.size()-1);
    45 }
    46 void IDAstar(int color,LL sta,int step){
    47     if(ok)return;
    48     if(n<8){
    49         if(sta==((LL)1<<n*n)-1){
    50             ok=1;
    51             return;
    52         }
    53     }else{
    54         if(sta==(LL)-1){
    55             ok=1;
    56             return;
    57         }
    58     }
    59     int h=Astar(color,sta);
    60     if(step+h>deep)return;
    61     for(int i=0;i<6;++i){
    62         memset(vis,0,sizeof(vis));
    63         LL s=dfs(0,0,i,sta);
    64         if(!state[s]){
    65             state[s]=1;
    66             IDAstar(i,s,step+1);
    67             state[s]=0;
    68         }
    69         if(ok)return;
    70     }
    71 }
    72 int main(void){
    73     while(scanf("%d",&n)){
    74         if(n==0)break;
    75         for(int i=0;i<n;++i)
    76         for(int j=0;j<n;++j)
    77             scanf("%d",&mp[i][j]);
    78         LL s=init();
    79         if(n<8){
    80             if(s==((LL)1<<(n*n))-1){
    81                 printf("0
    ");
    82                 continue;
    83             }
    84         }else{
    85             if(s==(LL)-1){
    86                 printf("0
    ");
    87                 continue;
    88             }
    89         }
    90         for(deep=1;!ok;deep++){
    91             state.clear();
    92             state[s]=1;
    93             IDAstar(mp[0][0],s,0);
    94         }
    95         printf("%d
    ",deep-1);
    96     }
    97 }
    View Code

    请教了下艾神,他说不要去重,太慢Orz

    好好想了下,好像确实有好多优化点:状态压缩,map去重,A*函数,每次都是dfs= =

    之后改进后直接用state[N][N]存储当前状态(1表示与mp[0][0]点相通的格点,2表示与mp[0][0]相通格点邻接的不同格点,0表示剩余格点),用memery[N][N]存储上一个状态;每次染色时判断有没有新增格点(state[i][j]==2&&mp[i][j]==color)有的话才染色;每次dfs的只是这次需要染色的格点域。如此复杂度大大降低了!但是还是TLE了好几发,仔细检查才发现是估价函数A*写搓了QAQ

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<set>
     6 #define N 8
     7 #define M 6
     8 #define met(x) memset(x,0,sizeof(x))
     9 using namespace std;
    10 int mp[N][N],n;
    11 int state[N][N];
    12 bool mark[M];
    13 int dx[]={0,1,0,-1};
    14 int dy[]={1,0,-1,0};
    15 void dfs(int px,int py,int color){
    16     state[px][py]=1;
    17     for(int i=0;i<4;++i){
    18         int x=px+dx[i];
    19         int y=py+dy[i];
    20         if(0<=x&&x<n&&0<=y&&y<n)
    21         if(state[x][y]!=1){
    22             if(mp[x][y]==color)dfs(x,y,color);
    23             else state[x][y]=2;
    24         }
    25     }
    26 }
    27 void init(){
    28     met(state);
    29     dfs(0,0,mp[0][0]);
    30 }
    31 int Astar(int color){
    32     int sum=0;
    33     met(mark);
    34     /**mark[color]=1; color不应该被mark,估价函数要写的好,搓一点都会TLE**/
    35     for(int i=0;i<n;++i)
    36     for(int j=0;j<n;++j)
    37         if(state[i][j]!=1&&!mark[mp[i][j]]){
    38             mark[mp[i][j]]=1;
    39             sum++;
    40         }
    41     return sum;
    42 }
    43 int cnt(int color){
    44     int sum=0;
    45     for(int i=0;i<n;++i)
    46     for(int j=0;j<n;++j)
    47     if(state[i][j]==2&&mp[i][j]==color){
    48         sum++;
    49         dfs(i,j,color);
    50     }
    51     return sum;
    52 }
    53 bool IDAstar(int deep,int color){
    54     if(deep<Astar(color))return 0;
    55     if(deep==0)return 1;
    56     for(int i=0;i<M;++i){
    57         int memery[N][N];
    58         memcpy(memery,state,sizeof(state));
    59         if(cnt(i)==0)continue;
    60         if(IDAstar(deep-1,i))return 1;
    61         memcpy(state,memery,sizeof(memery));
    62     }
    63     return 0;
    64 }
    65 void debug(int i){
    66     printf("
    -----debug %i -----
    ",i);
    67 }
    68 int main(void){
    69     while(scanf("%d",&n)){
    70         if(n==0)break;
    71         for(int i=0;i<n;++i)
    72         for(int j=0;j<n;++j)
    73             scanf("%d",&mp[i][j]);
    74         init();
    75         int deep=Astar(mp[0][0]);
    76         if(deep==0){
    77             printf("0
    ");
    78         }else{
    79             while(!IDAstar(deep,mp[0][0]))deep++;
    80             printf("%d
    ",deep);
    81         }
    82     }
    83 }
  • 相关阅读:
    tar.gz 查看原文件大小
    ssh2 和 ssh 的公钥转换
    MySQL binlog 导入
    app自动测试-微信(android)-web-1
    crontab中执行java程序的脚本
    tomcat 启动慢解决(/dev/random)
    app自动测试-微信(iOS)-web-1
    git
    java.lang.OutOfMemoryError: unable to create new native thread
    docker (centOS 7) 使用笔记6
  • 原文地址:https://www.cnblogs.com/barrier/p/5789218.html
Copyright © 2011-2022 走看看