博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 1020 Anniversary Cake
阅读量:7296 次
发布时间:2019-06-30

本文共 1649 字,大约阅读时间需要 5 分钟。

搜索

题意:先给出大方阵的边长,再给出m个小方阵并给出每个方阵的边长,问是否可以不发生重叠地把小方阵放进大方阵中,并且大方阵完全利用没有剩余

这题的代码不难写,关键是要找到策略,这题的策略比搜索本身的剪枝更有价值

摆放小方阵的策略是,尽可能往上面摆,然后尽可能往左边摆。另外有个策略一开始想错了,我是想先把小方阵排序,先放好大的,再放好小的,这样在摆放过程中可能出问题,画图可知,正确的策略是就目前的摆放情况,能放得到下哪个就放哪个,无所谓大小

 

为了满足尽可能放在左上方的条件,需要记录大方针的状态

col[i]的意义是,第i列,从最顶部数下来,被连续占据了多少格

注意在整个摆放过程中,每一列都保证是被连续占据的,不会出现断开的情况,这要求在搜索剪枝的时候处理好

 

#include 
#include
#include
using namespace std;#define N 55#define M 15int n,m;int col[N],s[M];bool dfs(int mm){ if(mm >= m) return true; int Min = N , c = 0; for(int i=1; i<=n; i++) if(col[i] < Min) { Min = col[i]; c = i; } for(int i=1; i<=10; i++) if(s[i]) { bool ok = true; if( !(c+i-1 <= n && col[c]+i <= n) ) continue; for(int k = c; k <= c+i-1; k++) if(col[k] != col[c]) { ok = false; break; } if(!ok) continue; s[i]--; for(int k=c; k <= c+i-1; k++) col[k] += i; if(dfs(mm+1)) return true; s[i]++; for(int k=c; k <= c+i-1; k++) col[k] -= i; } return false;}int main(){ int cas; cin >> cas; while(cas--) { int x,sum = 0; cin >> n >> m; memset(s,0,sizeof(s)); for(int i=0; i
> x; s[x]++; sum += x * x; } memset(col,0,sizeof(col)); if(sum != n * n || !dfs(0)) cout << "HUTUTU!" << endl; else cout << "KHOOOOB!" << endl; } return 0;}

 

转载地址:http://foynm.baihongyu.com/

你可能感兴趣的文章
A和B两个数组,删除B中与A重复的元素
查看>>
方格广搜
查看>>
match
查看>>
今日工作情况2
查看>>
一个学习简单网络技术的网站
查看>>
使用JQuery的get或post方法时出现页面没法手动刷新?
查看>>
MongoDB进阶
查看>>
python3csv与xlsx文件操作模块(csv、xlsxwriter)
查看>>
开启线程方式
查看>>
xdebug
查看>>
Css之 间距初始化
查看>>
lsnrctl启动报错,Linux Error: 29: Illegal seek
查看>>
IDEA github
查看>>
linux 驱动学习笔记05--文件系统与设备文件系统
查看>>
unresolved external symbol __forceAtlDllManifest错误的解决
查看>>
Linux的.run文件简单制作
查看>>
ubuntu解压命令(转)
查看>>
C#获取获取北京时间多种方法
查看>>
动态语言的灵活性是把双刃剑 -- 以 Python 语言为例
查看>>
1. 字节序的转换
查看>>