zoj1411_anniversary_dfs
来源:互联网 发布:java产生随机数的代码 编辑:程序博客网 时间:2024/06/14 09:27
// zoj1411_Anniversary_AC.cpp : Defines the entry point for the console application.// 题意中的side是边长的意思,square-shape是正方形的意思,题意就是问是否把边长为s的正方形大蛋糕正好切成n块正方形小蛋糕// 思路:把所有的蛋糕都看成是由边长为1的小蛋糕组成的,然后深搜#include "stdafx.h"#include<iostream>#include<string.h>#include<vector>using namespace std;//每一个请求者的信息struct rq{ int size;//请求的蛋糕的边长 bool isget;//该请求者的要求是否已得到满足};vector<rq> rqs;//请求者数组bool cake[41][41];//蛋糕//是否可以为当前请求分配蛋糕,index:当前位置,s:大蛋糕的边长,请求分配的小蛋糕的边长bool canget(int index, int s, int rs){ int x = index / s; int y = index%s; for (int i = x; i < x + rs; i++) for (int j = y; j < y + rs; j++) if (!cake[i][j]) return false; return true;}//为当前请求分配蛋糕,index:当前位置,s:大蛋糕的边长,请求分配的小蛋糕的边长void getcake(int index, int s, int rs){ int x = index / s; int y = index%s; for (int i = x; i < x + rs; i++) for (int j = y; j < y + rs; j++) cake[i][j] = false;}//撤销之前分配的蛋糕,index:当前位置,s:大蛋糕的边长,之前请求分配的小蛋糕的边长void retcake(int index, int s, int rs){ int x = index / s; int y = index%s; for (int i = x; i < x + rs; i++) for (int j = y; j < y + rs; j++) cake[i][j] = true;}//深搜bool dfs(int index, int s){ bool as = true;//allserve:所有请求都已经满足 for (int i = 0; i < rqs.size(); i++)//判断是否所有请求都已经满足 { if (!rqs[i].isget) { as = false; break; } } if (as) return true; else//还有请求没有得到满足 { for (int j = index; j < s*s; j++)//查找下一个可以分配的位置 { int x = j / s; int y = j%s; if (cake[x][y])//当前位置可以分配蛋糕 { bool cansuit[11];//当前位置是否可以为请求分配边长为i的小蛋糕(1<=i<=10),为了避免相同的请求值重复地进行递归查询 memset(cansuit, true, sizeof(cansuit)); for (int i = 0; i < rqs.size(); i++)//查找还没有得到满足的请求 if ((rqs[i].isget == false) && canget(j, s, rqs[i].size) && cansuit[rqs[i].size]) { getcake(j, s, rqs[i].size);//分配蛋糕 rqs[i].isget = true; if (dfs((j + rqs[i].size), s))//下一层递归查询,如果返回true则说明当前的分配是正确的,如果返回false说明当前的分配是错误的,说明之前的分配存在问题,要返回上一层重新分配(如果最终是可以满足所有分配的,则每一次递归都是有请求是可以满足的) return true; rqs[i].isget = false; retcake(j, s, rqs[i].size);//回收分配的蛋糕 cansuit[rqs[i].size] = false;//在当前位置,当前的请求值(请求分配的蛋糕的边长)是不可以满足最终的分配要求的,所以设置为false,避免后续请求中相同的请求值重复查询 } return false;//当前位置不可以(为剩余的还没有满足的蛋糕分配请求)分配蛋糕,说明之前的分配存在问题(假设最终是可以满足说有分配条件的,如果不满足则很明显所有的分配都是存在问题) } } return false;//找不到合适的下一个分配位置 }}int _tmain(int argc, _TCHAR* argv[]){ int t; cin >> t; for (int i = 0; i < t; i++) { int s, n; cin >> s >> n; int tsum = 0; rqs.clear(); for (int j = 0; j < n; j++) { rq trq; cin >> trq.size; trq.isget = false; rqs.push_back(trq); tsum += trq.size*trq.size; } if (tsum != s*s)//如果左右两边不等大很明显就是错误的 cout << "HUTUTU!" << endl; else { memset(cake, false, sizeof(cake)); for (int j = 0; j < s; j++) for (int k = 0; k < s; k++) cake[j][k] = true; if (dfs(0, s)) cout << "KHOOOOB!" << endl; else cout << "HUTUTU!" << endl; } } return 0;}
0 0