王道机试指南 例题9.4 Square
题目:
题目大意:给出一堆长度各异的木条,这些木条能否头尾相连构成一个正方形?
算法及分析:
深度优先遍历。
代码:
#include <iostream>
#include <string>
#include <cstring> //memset函数的头文件
#include <algorithm>
using namespace std;
//设计成全局变量,减少DFS函数的传参数量
const int MAXN=25;
int side;//正方形边长
int m;//木条数
int sticks[MAXN];//记录木条长度
int visit[MAXN];//记录该木条是否访问过
bool DFS(int sum,int count,int position){//深度优先遍历
if(count==3)
return true;
for(int i=position;i<m;i++){
if(visit[i]==1 || sum+sticks[i]>side)//如果该条边访问过或累加后长度大于正方形边长,则进入下一轮循环
continue;
sum+=sticks[i];
visit[i]=1;
if(sum==side){//刚好凑成一条边
if(DFS(0,count+1,0)==1)
return true;
}
else{//sum<side,还不够凑成一条边
if(DFS(sum,count,i+1)==1)
return true;
}
//本轮构造失败,则恢复sum并恢复访问标记
sum-=sticks[i];
visit[i]=0;
}
return false;
}
bool compare(int x,int y){//按从大到小排序
return x>y;
}
int main(){
int n;
cin>>n;
for(int k=0;k<n;k++){
cin>>m;
int total=0;
for(int j=0;j<m;j++){
cin>>sticks[j];
total+=sticks[j];
}
if(total%4!=0){//剪枝:如果总长度不能被4整除,则构造失败
cout<<"no"<<endl;
continue;
}
side=total/4;
sort(sticks,sticks+m,compare);//将木条按长度从大到小排序
if(sticks[0]>side){//剪枝:如果最长的木条长度超过正方形边长,则构造失败
cout<<"no"<<endl;
continue;
}
memset(visit,0,sizeof(visit));//初始化访问标记为0
if(DFS(0,0,0)==1)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
return 0;
}
运行结果:
拼多多集团-PDD公司氛围 753人发布
查看8道真题和解析