@Moritz
2019-03-26T04:24:58.000000Z
字数 1623
阅读 467
蓝桥杯
编程
C++
竞赛
所有文稿
DFS+全排列
/*16:26*/
/*16:52 输出296*/
/*16:59 debug完成 输出116*/
#include <iostream>
#include <cmath>
using namespace std;
int a[5][5],path[5],cnt=0,x[10][10];
void dfs(int m,int n,int inx){
if (x[m+1][n]==1){
x[m+1][n]=0;
dfs(m+1,n,inx);
}
if (x[m-1][n]==1){
x[m-1][n]=0;
dfs(m-1,n,inx);
}
if (x[m][n+1]==1){
x[m][n+1]=0;
dfs(m,n+1,inx);
}
if (x[m][n-1]==1){
x[m][n-1]=0;
dfs(m,n-1,inx);
}
}
bool yes(){
memset(x,0,sizeof(x));
for(int i=0;i<5;i++){
x[(path[i]-1)/4][(path[i]-1)%4]=1;//一开始写成了path[i]%4-1,很快debug完成
}
int tot=0;
for(int i=0;i<3;i++){
for(int j=0;j<4;j++){
if (x[i][j]==1) dfs(i,j,++tot);
}
}
if (tot==1) return true;
else return false;
}
void solve(int cur){
if (cur>=5){
if (yes()){
cnt++;
for(int i=0;i<5;i++) cout<<path[i]<<" ";
cout<<endl;
}
return;
}
else{
for(int i=1;i<=12;i++){
bool ok=true;
if (cur==0||i>path[cur-1]){
for(int j=0;j<cur;j++){
if (path[j]==i){
ok=false;
break;
}
}
if (ok){
path[cur]=i;
solve(cur+1);
}
}
}
}
}
int main(){
int temp=1;
for(int i=0;i<3;i++){
for(int j=0;j<4;j++){
a[i][j]=temp++;
}
}
solve(0);
cout<<cnt<<endl;
return 0;
}
这届蓝桥杯怎么这么难呢……
思路:枚举,设一个该数平方根为上线以提高运算速度。
对如何退出递归不熟练,参考了紫书上困难的串的代码才写出来
/*17:02*/
/*17:35 已完成 但复杂度太高 只能通过部分案例*/
#include <iostream>
#include <cmath>
using namespace std;
long long n,a[5],x;
int solve(int cur,long long ctot){
//printf("\ncur=%d ctot=%d\n",cur,ctot);
if (cur>=4){
if (ctot==n) return 0;//已经找到解
else return 1;
}
for(long long i=0;i<=sqrt(n*1.0);i++){
long long ttot=ctot+i*i;
//printf("ctot=%d\n",ttot);
if (ttot<=n){
a[cur]=i;
//printf("i=%d cur=%d ctot=%d\n",i,cur,ttot);
if (!solve(cur+1,ttot)) {
return 0;//已找到解
}
}
}
return 1;
}
int main(){
cin>>n;
solve(0,0);
for(int i=0;i<4;i++){
cout<<a[i]<<" ";}
system("pause");
return 0;
}
运行时间还是太长了,参考网上的做法,进行数据重复利用,用一个数组存放运算过的数,代码略。
效率似乎还是不够
2019.3.10