poj 1020 DFS +回溯

Source Code

Problem: 1020 User: sunyanfei
Memory: 700K Time: 32MS
Language: G++ Result: Accepted
    • Source Code
/*
 * Problem:poj 1020 zoj 1411
 * Type:DFS+回溯
 */
#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int cake_size,cake_number,cuted_cakes;//cute_cakes是已经放好的蛋糕数
int piece[11],column[41];//记录每列的占用情况,就是由上到下占到哪一行了
int DFS()
{
	int i,j;
	if(cuted_cakes==cake_number)return 1;
	int now_column=41,min_used_row=41;
	for(i=1;i<=cake_size;i++)
	{
		if(column[i]<min_used_row)
		{
			min_used_row=column[i];
			now_column=i;
		}
	}
	for(i=10;i>0;i--)//从大到小开始选择
	{
		if(piece[i]==0||i+now_column>cake_size+1|| i + min_used_row > cake_size + 1)
		{
			continue;
		}
		bool OK=true;
		for(j=now_column+1;j<now_column+i;j++)
		{
			if(column[j]>min_used_row)
			{
				OK=false;
				break;
			}
		}
		if(OK)//空间足够,递归回溯
		{
			for(j=now_column;j<now_column+i;j++)
			{
				column[j]+=i;
			}
			cuted_cakes++;
			piece[i]--;
			if(DFS())return 1;
			++piece[i];
			--cuted_cakes;
			for(j=now_column;j<now_column+i;++j)
			{
				column[j]-=i;
			}
		}
	}
	return 0;
}
int main()
{   setbuf(stdout,NULL);
	int t,piece_side,area;
    cin>>t;
    while(t--)
    {
    	int i;
    	cin>>cake_size>>cake_number;
    	memset(piece,0,sizeof(piece));
    	for(i=1;i<41;i++)
    	{
    		column[i]=1;
    	}
    	area=0;
    	for(i=0;i<cake_number;i++)
    	{
    		cin>>piece_side;
    		piece[piece_side]++;
    		area+=piece_side*piece_side;
    	}
    	if(area!=cake_size*cake_size)
    	{
    		cout<<"HUTUTU!"<<endl;continue;
    	}
    	cuted_cakes=0;
    	if(DFS())
    	{
    		cout<<"KHOOOOB!"<<endl;
    	}
    	else cout<<"HUTUTU!"<<endl;
    }
	return 0;
}

posted on 2011-08-15 20:42  lonelycatcher  阅读(298)  评论(0编辑  收藏  举报

导航