poj2362

题目链接: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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡定的小Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值