• HDU 4127 Floodit!【2011 ACM Asia Fuzhou Regional Problem G】


    现场时看到这题时感觉和前两天做的一个题目类似(POJ 3732),很早就开敲这题,结果超时了,之后看很少有人过又各种卡题就没去看这题了,今天做了下,稍微加点优化就过了,可惜了...

      

    状态不容易记录,很明显的IDA*题目,第一次做时每次都从(0,0)扫一遍染色,效率太低了,超时,改下做法:

    每个块被染色之后他就肯定和(0,0)点相同了,之后无论怎么染色不影响,那么图可以记录为3种状态,被染色过的点(1),下一次可以被染色的点(2) ,其他点(0),搜下去就好了,A*函数为未被染色的颜色的种类

     1 #include<cstdio>
    2 #include<cstring>
    3 using namespace std;
    4
    5 int maze[10][10],n;
    6 int vis[10][10];
    7 int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    8 void fill(int x,int y,int c){
    9 vis[x][y]=1;
    10 for(int i=0;i<4;i++){
    11 int tx=x+dir[i][0];
    12 int ty=y+dir[i][1];
    13 if(tx<0||ty<0||tx>=n||ty>=n) continue;
    14 if(vis[tx][ty]==1) continue;
    15 vis[tx][ty]=2;
    16 if(maze[tx][ty]==c) fill(tx,ty,c);
    17 }
    18 }
    19
    20 int exp(int col){
    21 int cnt=0;
    22 for(int i=0;i<n;i++){
    23 for(int j=0;j<n;j++){
    24 if(maze[i][j]!=col) continue;
    25 if(vis[i][j]==2){
    26 cnt++;
    27 fill(i,j,col);
    28 }
    29 }
    30 }
    31 return cnt;
    32 }
    33
    34 int h(){
    35 int col=0;
    36 for(int i=0;i<n;i++){
    37 for(int j=0;j<n;j++){
    38 if(vis[i][j]==1) continue;
    39 col|=1<<maze[i][j];
    40 }
    41 }
    42 int cnt=0;
    43 while(col){
    44 col&=(col-1);
    45 cnt++;
    46 }
    47 return cnt;
    48 }
    49
    50 int dep;
    51 bool dfs(int d){
    52 if(d==dep) return h()==0;
    53 if(h()+d>dep) return false;
    54
    55 for(int i=0;i<=5;i++){
    56 int tvis[10][10];
    57 memcpy(tvis,vis,sizeof(vis));
    58 if(exp(i)==0) continue;
    59 if(dfs(d+1)) return true;
    60 memcpy(vis,tvis,sizeof(vis));
    61 }
    62 return false;
    63 }
    64
    65 int main(){
    66 while(scanf("%d",&n),n){
    67 for(int i=0;i<n;i++){
    68 for(int j=0;j<n;j++){
    69 scanf("%d",&maze[i][j]);
    70 }
    71 }
    72 memset(vis,0,sizeof(vis));
    73 fill(0,0,maze[0][0]);
    74
    75 dep=0;
    76 while(true){
    77 if(dfs(0)) break;
    78 dep++;
    79 }
    80 printf("%d\n",dep);
    81 }
    82 }

       

      

    POJ 3732 Paint Me Less

    赛前刚做过的题目,这题是4×4的矩阵,但是每个点都可以染色,最后要求颜色为全为0

    某个块染色的时候只有染成0或者和周围四个块的某一个相同即可,其他颜色没必要去尝试,然后对每一层的状态加一个hash就能过了,A*为非0的颜色种类个数

      1 #include<cstdio>
    2 #include<cstring>
    3 #include<bitset>
    4 using namespace std;
    5
    6 int maze[5][5];
    7 bool ucol[20];
    8 int lx,ly;
    9
    10 int dep;
    11 inline int h(){
    12 bool col[20];
    13 memset(col,false,sizeof(col));
    14 for(int i=0;i<lx;i++){
    15 for(int j=0;j<ly;j++){
    16 col[maze[i][j]]=true;
    17 }
    18 }
    19 int cnt=0;
    20 for(int i=1;i<20;i++){
    21 cnt+=col[i];
    22 }
    23 return cnt;
    24 }
    25
    26 int dir[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
    27 void fill(int x,int y,int c){
    28 int tc=maze[x][y];
    29 maze[x][y]=c;
    30 for(int i=0;i<4;i++){
    31 int tx=x+dir[i][0];
    32 int ty=y+dir[i][1];
    33 if(tx<0||ty<0||tx>=lx||ty>=ly) continue;
    34 if(maze[tx][ty]!=tc) continue;
    35 fill(tx,ty,c);
    36 }
    37 }
    38
    39 bitset<1000007> vis[17];
    40 unsigned zip(){
    41 unsigned z=0;
    42 for(int i=0;i<lx;i++){
    43 for(int j=0;j<ly;j++){
    44 z=maze[i][j]+z*131;
    45 }
    46 }
    47 return z%1000007;
    48 }
    49
    50 int ans[20][3];
    51 bool dfs(int d){
    52 int th=h();
    53 if(d==dep) return !th;
    54 if(d+th>dep) return false;
    55 for(int i=0;i<lx;i++){
    56 for(int j=0;j<ly;j++){
    57 bool tcol[20];
    58 memset(tcol,false,sizeof(tcol));
    59 tcol[0]=true;
    60 for(int k=0;k<4;k++){
    61 int tx=i+dir[k][0];
    62 int ty=j+dir[k][1];
    63 if(tx<0||ty<0||tx>=lx||ty>=ly) continue;
    64 tcol[maze[tx][ty]]=true;
    65 }
    66 for(int k=0;k<20;k++){
    67 if(k==maze[i][j]) continue;
    68 if(!tcol[k]) continue;
    69 int tmp[5][5];
    70 memcpy(tmp,maze,sizeof(tmp));
    71 fill(i,j,k);
    72 ans[d][0]=i; ans[d][1]=j; ans[d][2]=k;
    73 int _z=zip();
    74 if(vis[d][_z]){
    75 memcpy(maze,tmp,sizeof(tmp));
    76 continue;
    77 }
    78 vis[d][_z]=true;
    79 if(dfs(d+1)) return true;
    80 memcpy(maze,tmp,sizeof(tmp));
    81 }
    82 }
    83 }
    84 return false;
    85 }
    86
    87
    88 int main(){
    89 while(~scanf("%d%d",&lx,&ly)){
    90 memset(ucol,false,sizeof(ucol));
    91 ucol[0]=true;
    92 for(int i=0;i<lx;i++){
    93 for(int j=0;j<ly;j++){
    94 scanf("%d",&maze[i][j]);
    95 ucol[maze[i][j]]=true;
    96 }
    97 }
    98 dep=0;
    99 while(true){
    100 for(int i=0;i<dep;i++) vis[i].reset();
    101 if(dfs(0)) break;
    102 dep++;
    103 }
    104 printf("%d\n",dep);
    105 for(int i=0;i<dep;i++){
    106 printf("%d %d %d\n",ans[i][0]+1,ans[i][1]+1,ans[i][2]);
    107 }
    108 }
    109 }




  • 相关阅读:
    初始面向对象
    python之路——迭代器和生成器
    函数进阶
    python之路——初识函数
    实现css两端对齐
    http
    background-size
    call和apply的区别
    js兼容性
    面试题
  • 原文地址:https://www.cnblogs.com/ambition/p/flood_it.html
Copyright © 2020-2023  润新知