Description

 给你一个n,问能否将1到n这n个整数进行排列,使得这个排列中任意两个相邻的数字和都是平方数。如果能,输出这个排列(如果存在多个,输出字典序最小的),否则输出-1。

 

Input

 输入一个整数n (1 <= n <= 15)

 

Output

 如果存在这样的排列(如果存在多个,输出字典序最小的),输出n个以空格隔开的整数表示这个排列,否则输出-1。

Sample Input

1

Sample Output

1

HINT

 

C++版本一

题解:

求上图的哈密顿路径

只有当n等于1和15时才存在

#include<bits/stdc++.h>
using namespace std;

int main() {
	int n;
	scanf("%d", &n);
	if(n == 1) printf("1\n"); 
	else if(n == 15) printf("8 1 15 10 6 3 13 12 4 5 11 14 2 7 9\n");
	else printf("-1\n");
	return 0;
} 

C++版本二

题解:

BFS

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <queue>
using namespace std;
typedef long long ll;
const int N=10000;
int t,n,m,flag;
int a[N],vis[N];
 
void bfs(int k){
    if(k==n+1){
        int f=1;
        for(int i=1;i<=n-1;i++){
            int tmp=(int)sqrt(a[i]+a[i+1]);
            if(a[i]+a[i+1]!=tmp*tmp){
                f=0;break;
            }
        }
        if(f){
            for(int i=1;i<=n-1;i++)
                printf("%d ",a[i]);
     
            printf("%d\n",a[n]);
            flag=1;
        }
        return;
    }
    for(int i=1;i<=n;i++){
        int tmp=(int)sqrt(i+a[k-1]);
            if(k>1&&i+a[k-1]!=tmp*tmp)
                continue;
        if(vis[i]==0&&flag==0){
            vis[i]=1;
            a[k]=i;
            bfs(k+1);
            vis[i]=0;
        }
    }
}
int main()
{
    flag=0;
    scanf("%d",&n);
    bfs(1);
    if(flag==0)
    printf("%d\n",-1);
    return 0;
}