现在的位置: 首页 > 综合 > 正文

poj2362

2013年12月13日 ⁄ 综合 ⁄ 共 1112字 ⁄ 字号 评论关闭

题目链接:http://poj.org/problem?id=2362

这道题和poj1011大致是一个意思,但是我用那道题的代码直接改来交上去却超时了,只能说明1011题的测试数据弱了,在这道题上,还可以有两个比较大的剪枝:

一、需要拼成正方形,只要拼成三条边,就可以判断能否拼成正方形了!

二、对数据的降序排列,为了减少重复设置搜索起点,即如果剩余的边需拼成的长度大于本身棒的长度,则下次开始搜索的时候就直接从该棒开始而不用从头开始了!

下面的代码是我在1011题的基础上更改的,写的很不好,没有纯粹的写一道题的程序出来更简洁,不过人懒了,改改也过了!

#include<iostream>///找最小的长度的
#include<algorithm>
using namespace std;
int stick[70],n,sign;
bool vis[70];
int cmp(const void *a,const void *b)
{
	return *(int *)b-*(int *)a;
}
int fun(int i,int m,int t,int begin)//需要匹配的长度,已经匹配的段数,这一小段还需要的长度
{
	int j;
     if(t==0 && m==n)//一个段都已经匹配完了
	 {
		 sign=1;
		 return i;
	 }
	 if(t==0)
		 t=i;
	 for(j=begin; j<n; j++)
	 {
		 if(vis[j]==false)//就是可以的
		 {
			 vis[j]=true;
			 if(stick[j]<t)
			 {
                 if(fun(i,m+1,t-stick[j],j))
				    return i;//不然就继续走了
			 }
			 if(stick[j]==t)
			 {
                  if(fun(i,m+1,t-stick[j],0))
				    return i;//不然就继续走了
			 }
			 vis[j]=false;
			 if(t==i || t==stick[j])//似乎明白了,如果t==i的话则找不到一个和它匹配的棍子的,
				 break;
			 while(stick[j]==stick[j+1])
				 j++;
		 } 
	 }
	 return 0;
}
int main()
{
	int i,j,k,sum,m;
	scanf("%d",&m);
	while(m--)
	{
		sign=0;
		sum=0;
		scanf("%d",&n);
		for(i=0; i<n; i++)
		{
			scanf("%d",&stick[i]);
			sum+=stick[i];
			vis[i]=false; 
		}
		qsort(stick,n,sizeof(int),cmp);//降序排列的
		fun(sum/4,0,sum/4,0);//返回的不是1
			if(sign==1)
				printf("yes\n");
			else
		        printf("no\n",i);
	}
	return 0;
}

 

抱歉!评论已关闭.