poj 1020dfs

来源:互联网 发布:淘宝店铺权重如何提升 编辑:程序博客网 时间:2024/06/02 14:17

从一个顶点开始,一行一行堆,先堆灵活度小的(大体积),后堆灵活度大的(小体积)。

不管怎么堆,dfs肯定能遍历所有堆法,但是用以上的堆法可以更快速的找到答案

比如从左上角开始,先堆满第一行,再第二行……知道n个小方块都塞进去了,表示找到答案,可以return了。


总结:做dfs一定一定要注意好完全的回溯,如果回溯,所有与判断有关的全局变量一定要还原,这题由于没有注意到高度的还原WA2次。

#include<iostream>  #include<map>#include<string>   #include<algorithm>  #include<fstream>#include<cmath>  #include<vector>#include<queue>#include<map>#include<math.h>using namespace std;  #define lch(i) ((i)<<1)  #define rch(i) ((i)<<1|1)  #define sqr(i) ((i)*(i))  #define pii pair<int,int>  #define mp make_pair  #define FOR(i,b,e) for(int i=b;i<=e;i++)  #define FORE(i,b,e) for(int i=b;i>=e;i--)  #define ms(a)   memset(a,0,sizeof(a))  const int maxnum =21252;const  int  mod = 10007;int n,m;int h[41];int cake[17];bool takein[17];bool dfs(int num,int nth,int row,int col){ //x:1~m;y:1~m;int side = cake[nth];if(col+side-1>m)return false;FOR(i,col,col+side-1){if(h[i]>=row||h[i]+side>m)return false;}FOR(i,col,col+side-1)h[i]+=side;if(num==n)return true;int nextrow=row,nextcol=col+side;if(nextcol>m){nextcol-=m;}int lowesth=1;FOR(i,1,m){if(h[nextcol]<row){lowesth=nextcol;break;}if(h[nextcol]<h[lowesth])lowesth=nextcol;nextcol=(nextcol)%m+1;}nextcol=lowesth;nextrow = h[nextcol]+1; int unfit=0;FOR(i,0,n-1){if(takein[i]||unfit==cake[i]) continue;takein[i]=1;if(dfs(num+1,i,nextrow,nextcol))return true;takein[i]=0;unfit=cake[i];}FOR(i,col,col+side-1)h[i]-=side;return false;}int cmp(const void* a,const void* b){return *(int*)b-*(int*)a;}int main()    {  #ifdef _DEBUG_fstream fin("G:/1.txt");#else#define fin cin#endifint t;fin>>t;while(t--){fin>>m>>n;ms(h);ms(takein);ms(cake);int sum1 = sqr(m),sum2=0;FOR(i,0,n-1){fin>>cake[i];sum2+=sqr(cake[i]);}if(sum1!=sum2){printf("HUTUTU!\n");continue;}qsort(cake,n,sizeof(int),cmp);int unfit =0,flag=1;FOR(i,0,n-1){if(unfit==cake[i])continue;takein[i]=1;if(dfs(1,i,1,1)){printf("KHOOOOB!\n");flag=0;break;}takein[i]=0;unfit=cake[i];}if(flag)printf("HUTUTU!\n");}    return 0;  } 


0 0