hdu1518 利用搜索外加回溯,每次只搜索一条边,当能组成一条边之后才去搜索另外一条边。
visit数组是用来设置访问标志的。
find(x,cnt,k); x当前组成的长度,cnt已经组成了多少正方形的边了。k已经搜索到几根木棍了。
ac代码
/*************************************************************************
> File Name: backup.cpp
> Author: zwy
> Mail: zwy_qz@hotmail.com
> Created Time: 2012年11月20日 星期二 11时47分16秒
************************************************************************/
#include<stdio.h>
#include<iostream>
using namespace std;
int ave;
int stick[29];
int n;
int visit[29];
bool find(int x,int cnt, int k)
{
int i;
if( x == ave)
{
if(cnt == 2) return true;
return find(0,cnt + 1 ,0 );
}
if(x <= ave)
{
for(i = k ; i < n ; i++)
if(!visit[i])
{
visit[i] = 1;
if(find(x + stick[i], cnt ,i+1))
return true;
visit[i] = 0 ;
}
}
return false;
}
int main()
{
int i;
int m,sum;
scanf("%d",&m);
while(m--)
{
sum = 0 ;
int max = -1;
scanf("%d",&n);
for(i = 0 ; i < n ; i++)
{
visit[i] = 0;
scanf("%d",&stick[i]);
sum += stick[i];
if(max < stick[i]) max = stick[i];
}
if(sum % 4 || max > sum / 4)
{
printf("no\n");
continue;
}
// printf("************\n");
ave = sum / 4;
if(find(0,0,0))
printf("yes\n");
else
printf("no\n");
}
return 0;
}
bug的代码。。。一直超时。。
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int ave ;
int stick[29];
int n;
int sum[29];
int visit[29];
/*bool find(int x1,int x2,int x3,int k)
{
if(x1 == ave && x2 == ave && x3 == ave)
{
// printf("x1 = %d x2 = %d x3 = %d \n",x1,x2,x3);
return true;
}
else
if(x1 <= ave && x2 <= ave && x3 <= ave && k >= 0)
{
if( x1 + stick[0] > ave && x2 + stick[0] > ave && x3 + stick[0] > ave ) return false;
if( x1 + sum[k] < ave || x2 + sum[k] < ave || x3 + sum[k] < ave ) return false;
return find(x1 + stick[k],x2,x3,k-1) || find(x1,x2 + stick[k],x3,k-1) || find(x1,x2,x3+stick[k],k-1) || find(x1,x2,x3,k-1);
}
return false;
}*/
bool find(int x1,int cnt,int k)
{
int i;
if(x1 == ave)
{
cnt ++;
if(cnt == 3) return true;
x1 = 0 ; k = n - 1;
}
if(x1 < ave)
{
for(i = k ; i >= 0 ; i--)
if(!visit[i])
{
visit[i] = 1;
if (find(x1 + stick[i],cnt ,k--)) return true;
visit[i] = 0 ;
}
}
return false;
}
int main()
{
int i,total;
int max;
scanf("%d\n",&n);
while(scanf("%d",&n)!=EOF)
{
total = 0;
max = -1;
for(i = 0 ; i < n ; i++)
{
scanf("%d",&stick[i]);
total += stick[i];
if(max < stick[i]) max = stick[i];
}
ave = total / 4 ;
sort(stick,stick+n);
sum[0] = stick[0];
for(i = 1 ; i < n ; i++)
sum[i] = sum[i-1] +stick[i];
for(i = 0 ; i < n ; i ++) visit[i] = 0;
//for(i = 0 ; i < n ; i++)
// printf("%d ",sum[i]);
//printf("\n");
if((double)ave != total * 1.0 / 4 || max > ave)
{
printf("no\n");
continue;
}
if(find(0,0,n-1))
{
printf("yes\n");
}
else
{
printf("no\n");
}
}
return 0;
}