北大ACM(POJ1020-Anniversary Cake)

Question:http://poj.org/problem?id=1020
问题点:DFS。
 1 Memory: 260K        Time: 47MS
 2 Language: C++        Result: Accepted
 3 
 4 #include <iostream>
 5 using namespace std;
 6 
 7 int mat[40];//按列记录小块Cake填充状态
 8 int side[16];//小块Cake边长
 9 bool visit[16];//小块Cake是否已使用
10 int width,cnt;//大块Cake边长 小块Cake数量
11 bool flag;//是否能被填充标志
12 int cmp(const void* a,const void* b)
13 {
14     return *(int*)b - *(int*)a;//降序排列
15 }
16 //状态更新:    pn为1时,从x列开始填充第idx块Cake,并判断是否能填充进去
17 //            pn为-1时,从x列开始清除第idx块Cake
18 bool update(int idx,int x,int pn)
19 {
20     int i,temp = mat[x];
21     if(pn == 1)
22     {
23         //填充第idx块Cake后,长宽不能超过边界
24         if(side[idx] + x > width || mat[x] + side[idx] > width) return false;
25         //判断x列到x+side[idx]-1列 是否同高度
26         for(i=1;i<side[idx];i++)
27         {
28             if(temp != mat[x+i]) return false;
29         }
30         visit[idx] = true;
31     }
32     else
33     {
34         visit[idx] = false;
35     }
36     for(i=0;i<side[idx];i++)
37     {
38         mat[x+i] += side[idx]*pn;
39     }
40     return true;
41 }
42 //获取当前最小高度处的最小列,填充顺序为"从低到高,从左到右"
43 int getLowX()
44 {
45     int i,temp=100;
46     for(i=0;i<width;i++)
47     {
48         temp =(temp<mat[i]?temp:mat[i]);
49     }
50     for(i=0;i<width && temp!= mat[i];i++);
51     return i;
52 }
53 //idx为已填充数 ,x为小块Cake编号
54 void dfs(int idx,int x)
55 {
56     if(idx == cnt) {//当全部填充完毕时,返回true
57         flag = true;
58         return;
59     }
60     for(int i=0,w=0;i<cnt;i++)
61     {
62         if(visit[i]) continue;//已填充的不再填充
63         if(w == side[i]) continue; else w = side[i];//同边长的不重复填充
64         if(update(i,x,1))//在x列填充第i块Cake
65         {
66             dfs(idx+1,getLowX());
67             if(flag) return;
68             update(i,x,-1);//在x列清除第i块Cake
69         }
70     }
71 }
72 int main()
73 {
74     int eg;
75     cin>>eg;
76     while(eg--)
77     {
78         int i,j,k;
79         memset(mat,0,sizeof(mat));
80         memset(side,0,sizeof(side));
81         memset(visit,0,sizeof(visit));
82         flag = false;
83         cin>>width;
84         cin>>cnt;
85         for(i=0;i<cnt;i++)
86         {
87             cin>>side[i];
88         }
89         qsort(side,cnt,sizeof(int),cmp);//排序用于去重
90         dfs(0,0);
91         if(flag) cout<<"KHOOOOB!"<<endl;
92         else cout<<"HUTUTU!"<<endl;
93     }
94     //system("pause");
95     return 0;
96 }

 

转载于:https://www.cnblogs.com/TYcnblogs/p/poj1020.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值