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;

}

你可能感兴趣的:(poj)