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
原创粉丝点击