z0j1008Gnome Tetravex

该题是找满足条件的摆法,直接DFS会超时,关键是压缩存储,同一种正方形只存一次,再DFS,然后搜到一种成功的就要退出,不要把所有可能的摆法都搜完,不然也会超时。初始化种类数不要忘记。

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 bool flag ;  //成功标志
 4 int n,kinds;  //正方形的个数为n*n,种类为kinds
 5 struct square
 6 {
 7     int top,bottom,left,right;
 8     int num;  //该类正方行的个数
 9 } rect[26];//记录每个正方形的状况
10 int map[26] ;//正方形的摆法
11 //铺第x个正方形
12 void dfs(int x)
13 {
14     int i; // 循环变量
15     if(x == n*n)  //成功标志
16     {
17         flag = true ;
18         return ;
19     }
20     if(flag)         return ;    //已找到一种正确的摆法,停止搜索,重要
21     for(i=0 ; i < kinds; i++)
22     {
23         if((rect[i].num != 0) &&   //判断是否可以摆这类正方形
24                 (x%n == 0 || rect[i].left == rect[map[x-1]].right)&&
25                 (x/n == 0 ||rect[i].top == rect[map[x-n]].bottom) )
26         {
27             rect[i].num--;  //可以,用掉正方形一个
28             map[x]= i;
29             dfs(x+1);
30             rect[i].num++;  //未成功,换下一种,正方形数量加回来
31         }
32     }
33 }
34 int main()
35 {
36 //    freopen("in.cpp","r",stdin);
37     int i,k;
38     bool showed;  //标记是否出现新类型的正方形
39     int ser = 0; //序列号
40     struct square temp; //读正方形
41        temp.num = 1;
42     while(true)
43     {
44         kinds = 0;  //初始化,重要
45         flag = false;
46         scanf("%d",&n);
47         if(n == 0 ) break;
48         ser++;
49         if(ser > 1)  puts("");
50         for(i = 0; i < n*n; i++)
51         {
52             scanf("%d%d%d%d",&temp.top,
53                   &temp.right,&temp.bottom,&temp.left);
54             showed = true;
55             for(k = 0; k < kinds; k++)
56             {
57                 if(rect[k].bottom== temp.bottom
58                    &&rect[k].top == temp.top
59                    &&rect[k].left == temp.left
60                    &&rect[k].right == temp.right)
61                 {
62                     showed = false;  //未出现新类型
63                     rect[k].num++;
64                     break;
65                 }
66             }
67             if(showed)//出现新类型
68             {
69                 rect[kinds] = temp;
70                 kinds++;
71             }
72         }
73         dfs(0);//从第0个铺起
74         if(flag == true)
75             printf("Game %d: Possible\n",ser);
76         else
77             printf("Game %d: Impossible\n",ser );
78     }
79     return 0;
80 }

 

posted on 2013-03-15 16:57  allh123  阅读(156)  评论(0编辑  收藏  举报

导航