• (DFS)zoj1008-Gnome Tetravex


    现在zoj暂时关了,实际上是在scuoj上做的。

    题目地址

    看起来题目比较复杂,实际上主要需要思维的是如何恰当的剪枝及合适的DFS角度。

    问题等价于将n*n个可能相同的方块放到一个n*n的表中,使满足题目要求的条件。由于放的时候是一个个放的,所以可以以此为切入点进行DFS,并且,只需要关注不同方块的种类,这样就可以极大的节约时间(从人做这件事的角度来看,相同的方块就像是相同的积木一样,人关注的只是相同的积木的形状以及个数。)

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 int a[25][4],kind[25],n,kge,b[25][4],cnt=0,m;//a记录不同种类方块各方向的数,kind记录每种种类的个数,kge记录种类数
     5 int dfs(int p)
     6 {
     7     if(p==m)//dfs成功的话,就是进行到第n*n次(这时前0——n*n-1都已经放好)
     8         return 1;
     9     else
    10     {
    11         for(int i=0;i<kge;i++)
    12         {
    13             if(kind[i]==0)
    14                 continue;
    15             else
    16             {
    17                 if(p%n!=0)//p%n时左侧就没有方块
    18                 {
    19                     if(b[p-1][1]!=a[i][3])
    20                         continue;
    21                 }
    22                 if(p>=n)//p<n时在最上一行,上面就没有方块
    23                 {
    24                     if(b[p-n][2]!=a[i][0])
    25                         continue;
    26                 }
    27                 kind[i]--;
    28                 for(int j=0;j<4;j++)
    29                 {
    30                     b[p][j]=a[i][j];
    31                 }
    32                 if(dfs(p+1))//继续dfs下一个位置
    33                 {
    34                     return 1;
    35                 }
    36                 kind[i]++;//如果这样并不行,恢复至之前的状态
    37             }
    38         }
    39         return 0;
    40     }
    41 }
    42 int main()
    43 {
    44     while(scanf("%d",&n))
    45     {
    46         kge=0;
    47         if(n==0)
    48             break;
    49         else
    50         {
    51             int up,left,right,down,i,j;
    52             m=n*n;
    53             for(i=0;i<m;i++)
    54             {
    55                 scanf("%d%d%d%d",&up,&right,&down,&left);
    56                 for(j=0;j<kge;j++)
    57                 {
    58                     if(a[j][0]==up&&a[j][1]==right&&a[j][2]==down&&a[j][3]==left)
    59                     {
    60                         kind[j]++;
    61                         break;
    62                     }
    63                 }
    64                 if(j==kge)//整体是对有无与之前的方块相同的判断
    65                     {
    66                         a[kge][0]=up;
    67                         a[kge][1]=right;
    68                         a[kge][2]=down;
    69                         a[kge][3]=left;
    70                         kind[kge]=1;
    71                         kge++;
    72                     }
    73             }
    74             if(cnt)
    75                 puts("");//注意空行
    76             if(dfs(0))
    77                 printf("Game %d: Possible
    ",++cnt);
    78             else
    79                 printf("Game %d: Impossible
    ",++cnt);
    80         }
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    MYSQL编码转换的问题latin1转utf8
    Java中的局部内部类
    Java中的抽象类和接口
    Java中的构造方法
    使用Java打印杨辉三角
    Java中的数组越界问题
    Java虚拟机中的内存分配
    关于iOS10 Xcode8真机测试项目出现的问题 "code signing is required for product type 'xxxxx' in SDK 'iOS 10.0"..
    Java语言的学习
    关于导航栏设置状态栏样式问题
  • 原文地址:https://www.cnblogs.com/quintessence/p/6030356.html
Copyright © 2020-2023  润新知