// 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;
}
zoj1411_anniversary_dfs
最新推荐文章于 2017-11-01 21:53:42 发布