Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 21988 | Accepted: 7691 |
Description
Input
Output
Sample Input
3 4 1 1 1 1 5 10 20 30 40 50 8 1 7 2 6 4 4 3 5
Sample Output
yes no yes
Source
很不错的一道题,就是说 给若干个小木棍,看是否能拼成一个正方形形,拼成一个矩形要满足所有木棍的总长度对4取余等于0,还得满足最长的一根小木棍不能长于所拼成正方形的边长。
正常考虑,要所围成的图形为正方形,需要检测一条边和别的边长度加到一块是否为正方形的边长,这个边长可能为一个木棍,也可能是两个木棍,三个木棍,四个,五个.....
计算时 计算到当前所加的木棍长度,如果当前的长度加上下一个木棍的长度大于所拼成正方形的边长,则不能判定为次状态无解,可能是加上别的一条,两条,三条...等于了所求的边长,如果把所有的情况加上了依然无解,依旧不能断定次木棍不能组成矩形,还可能当前本身加上的木棍长度就不合理,所以本题不用深搜无解
深搜(深入优先搜索(DFS)),当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,算法复杂度很高,就是把所有的点都遍历了一遍,不过代码很简单,很容易写,毕竟是时间复杂度为(O(n!));
本题大致做法就是对所有小棒子长度求和sum,sum就是正方形的周长,sum/4就是边长side。
问题就转变为:这堆小棒子能否刚好组合成为4根长度均为side的大棒子
不难了解,小棒子的长度越长,其灵活性越差。例如长度为5的一根棒子的组合方式要比5根长度为1的棒子的组合方式少,这就是灵活性的体现。
由此,我们首先要对这堆小棒子降序排序,从最长的棒子开始进行DFS
剪枝,有3处可剪:
1、 要组合为正方形,必须满足sum%4==0;
2、 所有小棒子中最长的一根,必须满足Max_length <= side,这是因为小棒子不能折断;
3、 当满足条件1、2时,只需要能组合3条边,就能确定这堆棒子可以组合为正方形。
附ac代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int a[21],i,j,k,l,m,n,mid,vis[1000],num; long sum; int dfs(int num,int len,int s) { if(num==3) //如果已经得到的可构成变长的数位3 则不需要计算,剩下的一定能构成 return 1; for(int i=s;i<=n;i++) { if(vis[i]) //如果该木棍已经被使用,则无法继续使用 continue; vis[i]=1; //如果该木棍未被使用,则把该木棍标记为已经使用过了 if(len+a[i]<mid) //得到的当前长度未达到边长 { if(dfs(num,len+a[i],i)) //继续访问下一个 return 1; } else if(len+a[i]==mid) //得到的当前长度达到边长 { if(dfs(num+1,0,1)) //num+1,当前长度记为0; return 1; } vis[i]=0; //如果未到达要求,释放该点,以备下次别的情况访问 } return 0; } int main() { scanf("%d",&m); while(m--) { scanf("%d",&n); sum=0; for(i=1;i<=n;i++) { scanf("%d",&a[i]); sum+=a[i];//先求和,得到总长度。 } sort(a+1,a+n+1);//将所有的 木棍进行从小到大排序,sort里边逗号是该数组最后一个成员的地址的下一位 mid=sum/4;//在进行除法,得到边长 if(mid*4!=sum)//如果边长非整数 ,则不需要计算 //if(sum%4) printf("no\n"); else if(a[n]>mid)//如果最长的边大于了边长,因为小木棍不可分割,所以也不需要判断 printf("no\n"); else { num=0; memset(vis,0,sizeof(vis)); if(dfs(0,0,1))//第一个0代表 已经得到的可构成的边长数,第二个代表当前所得木棍和的长度,1代表搜索的地址 printf("yes\n"); else printf("no\n"); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/z8110/article/details/48003467