全排列
分治与递归
递归是实现分治的一种方法
思想思路
题目:
全排列i
我这样直接输出会多输出一个空行(最后一个\n)
#include<stdio.h>
using namespace std;
const int maxn=10;
int an[maxn];
int n;
bool hash[maxn]={0};
int c=0;
void pl(int index)
{
if (index>n-1)
{
for (int i=0;i<n-1;i++)
printf("%d ",an[i]);
printf("%d",an[n-1]);
printf("\n");
return;
}
for(int i=1;i<=n;i++)
{
if (!hash[i])
{
an[index]=i;
hash[i]=1;
pl(index+1);
c++;
hash[i]=0;
}
}
}
int main()
{
scanf("%d",&n);pl(0);
}
使用vector存储,在最后一格时不输出
参考解答
#include <cstdio>
#include <vector>
using namespace std;
const int MAXN = 8 + 1;
vector<vector<int> > result;
vector<int> temp;
int n;
bool used[MAXN] = {false};
void DFS(int idx) {
if (idx == n + 1) {
result.push_back(temp);
return;
}
for (int i = 1; i <= n; i++) {
if (!used[i]) {
temp.push_back(i);
used[i] = true;
DFS(idx + 1);
used[i] = false;
temp.pop_back();
}
}
}
int main() {
scanf("%d", &n);
DFS(1);
for (int i = 0; i < result.size(); i++) {
for (int j = 0; j < result[i].size(); j++) {
printf("%d", result[i][j]);
printf(j + 1 < result[i].size() ? " " : "\n");
}
}
return 0;
}
我也改好了
#include<stdio.h>
#include<vector>
using namespace std;
const int maxn=10;
//int an[maxn];
vector<vector<int> > ans;
vector<int> temp;
int n;
bool hasha[maxn]={0};
int c=0;
void pl(int index)
{
if (index>n-1)
{
//for(int j=0;j<temp.size();j++)printf("%d ",temp[j]);
ans.push_back(temp);
// for (int i=0;i<n-1;i++)
// printf("%d ",an[i]);
// printf("%d",an[n-1]);
// printf("\n");
// return;
}
for(int i=1;i<=n;i++)
{
if (!hasha[i])
{
temp.push_back(i);
hasha[i]=1;
pl(index+1);
hasha[i]=0;
temp.pop_back();
// an[index]=i;
// hash[i]=1;
// pl(index+1);
// c++;
// hash[i]=0;
}
}
}
int main()
{
scanf("%d",&n);pl(0);
for(int i=0;i<ans.size();i++)
{
for(int j=0;j<n;j++)
{
printf("%d",ans[i][j]);
if (j<n-1)printf(" ");
}
if(i<ans.size()-1)printf("\n");
}
}
N皇后
判断8皇后
弃用数组,研究vector的用法搞了半天关于vector的一些菜鸟吐槽-CSDN博客
首先弄明白bool
true是1,false是0
用了二维vector,加上各种边界条件总算搞出来了
可是时间复杂度on3
#include<stdio.h>
#include<vector>
#include<iostream>
using namespace std;
int n=8;
vector<vector<int> > a=vector<vector<int> >(8, vector<int>(8, 0));;
// vector<vector<int> > board = vector<vector<int> >(8, vector<int>(8, 0));
int jud(int n,vector<vector<int> > a)//??
{int sum1=0,sum2=0;
for(int i=0;i<n;i++)
{sum1=0;sum2=0;
for(int j=0;j<n;j++)
{sum1+=a[i][j];sum2+=a[j][i];
//行和为1,列和为1
// printf("##??--%d%d%dn%dj%d-\n",i,sum1,sum2,n,j) ;
if(a[i][j]==1)
{
for(int k=0;k<n;k++)
{
if(i+j-k<n&&i+j-k>=0&&i+j-k!=i)
{
if(a[i+j-k][j]==a[i][j])
{return false;}
}
if(k+j-i<n&&k+j-i>=0&&k!=i)
{
if(a[k][k+j-i]==a[i][j])
{return false;}
}
}
}
else if (a[i][j]!=0) {return false;}
// printf("#--%d%d%d-\n",i,sum1,sum2) ;
}
if(sum1!=1||sum2!=1) {return false;}
}
return true;}
int main()
{
int n1=8;
int ins;
int b[n1][n1];
//printf("%d %d",bool(true),bool(false));
for(int i=0;i<n1;i++)
for(int j=0;j<n1;j++)
{scanf("%d",&ins);a[i][j]=ins;}
//printf("%d",jud(n1,a));
if(jud(n1,a))printf("YES"); else printf("NO");
}
事实上答案只用了1-D数组(1的单坐标),并且遍历比我少一半(j>i)即可,减少重复
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
bool isValidQueenPlacement(const vector<vector<int>>& board) {
int n = board.size();
vector<int> positions(n, -1); // positions[i] 表示第 i 行的皇后所在的列
// 遍历棋盘,找出所有皇后的位置
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 1) {
positions[i] = j;
}
}
}
// 检查皇后之间的冲突
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// 检查是否有两个皇后在同一列
if (positions[i] == positions[j]) {
return false;
}
// 检查是否有两个皇后在同一对角线上
if (abs(positions[i] - positions[j]) == abs(i - j)) {
return false;
}
}
}
return true;
}
int main() {
vector<vector<int>> board = vector<vector<int>>(8, vector<int>(8, 0));
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
cin >> board[i][j];
}
}
cout << (isValidQueenPlacement(board) ? "YES" : "NO") << endl;
判断这里也巧用绝对值
不过他没有判断皇后同行,似乎是包含在这两个之中了。?
N皇后
·和全排列一样,需要使用hashtable记录某个数字是否被使用
这个错代码看了好多遍了,愣是没发现错在哪
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int N=9;
vector<vector<int> > a;
vector<int> temp;
int hashe1[N+2]={0};
void p(int index,int n)
{
if (index==n)
{printf("?");
a.push_back(temp);
}
for(int i=1;i<n;i++)
{
if(hashe1[i]==0)
for (int j=0;j<index;j++)
{
temp.push_back(i);
hashe1[i]=1;
p(index+1,n);
hashe1[i]=0;
temp.pop_back();
}
}
}
//}
int main()
{int n=8;
p(0,n);printf("%d",a.size());
}
,对比我自己上次写的全排列,才发现是循环多套了一层。构造排列之后直接判断+pushback还原现场一系列操作即可,但是你却多搞了个j从1-n?
改了还是错
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int N=9;
vector<vector<int> > a;
vector<int> temp;
int hashe1[N+2]={0};
void p(int index,int n)
{
if (index==n)
{printf("?");
a.push_back(temp);
}
for(int i=1;i<n;i++)
{
if(hashe1[i]==0)
{
temp.push_back(i);
hashe1[i]=1;
p(index+1,n);
hashe1[i]=0;
temp.pop_back();
}
}
}
//}
int main()
{int n=8;
p(0,n);printf("%d",a.size());
}
艹!少了个等于!i从1~n,我写的i<n...
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int N=9;
vector<vector<int> > a;
vector<int> temp;
int hashe1[N+2]={0};
void p(int index,int n)
{
if (index>n-1)
{printf("?");
a.push_back(temp);
}
for(int i=1;i<=n;i++)
{
if(hashe1[i]==0)
{
temp.push_back(i);
hashe1[i]=1;
p(index+1,n);
hashe1[i]=0;
temp.pop_back();
}
}
}
//}
int main()
{int n=8;
p(0,n);printf("%d",a.size());
}
这下至少构造排列部分对了
然后输出还是0,崩了
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int N=9;
vector<vector<int> > a;
vector<int> temp;
int hashe1[N+2]={0};
bool flag=0;
//bool j(vector<int> a)
//{
// for(int i=0;i<a.size();i++)
// {//不用判断同行同列,因为造出了是排列
// for(int j=i+1;i<a.size();j++)
// {
// if(abs(a[j]-a[i])==j-i) return false;
// }
// }
// return true;
// }
void p(int index,int n)
{
if (index==n)
{
a.push_back(temp);return;
}
for(int i=1;i<=n;i++)
{
if(hashe1[i]==0)
{
if(index==0)
{
temp.push_back(i);
hashe1[i]=1;
p(index+1,n);
hashe1[i]=0;
temp.pop_back();
}
else{
//printf("?");
// flag=0;
for(int k=0;k<index;k++)
{//printf("**%d %d %d %d.\n",k,index,temp[k],i);
if(abs(i-temp[k])==abs(index-k))
{//printf("*%d %d %d %d.\n",k,index,temp[k],i);
flag=1;break;}
}
if(!flag)
{//printf("**");
temp.push_back(i);
hashe1[i]=1;
p(index+1,n);
hashe1[i]=0;
temp.pop_back();
}
}
}
}
}
//}
int main()
{int n=8;
p(0,n);printf("%d",a.size());
}
竟是因为少了个flag归零。蹦
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int N=9;
vector<vector<int> > a;
vector<int> temp;
int hashe1[N+2]={0};
bool flag=0;
//bool j(vector<int> a)
//{
// for(int i=0;i<a.size();i++)
// {//不用判断同行同列,因为造出了是排列
// for(int j=i+1;i<a.size();j++)
// {
// if(abs(a[j]-a[i])==j-i) return false;
// }
// }
// return true;
// }
void p(int index,int n)
{
if (index==n)
{
a.push_back(temp);return;
}
for(int i=1;i<=n;i++)
{
if(hashe1[i]==0)
{
if(index==0)
{
temp.push_back(i);
hashe1[i]=1;
p(index+1,n);
hashe1[i]=0;
temp.pop_back();
}
else{
//printf("?");
flag=0;//这句话害我浪费一个晚上
for(int k=0;k<index;k++)
{//printf("**%d %d %d %d.\n",k,index,temp[k],i);
if(abs(i-temp[k])==abs(index-k))
{//printf("*%d %d %d %d.\n",k,index,temp[k],i);
flag=1;break;}
}
if(!flag)
{//printf("**");
temp.push_back(i);
hashe1[i]=1;
p(index+1,n);
hashe1[i]=0;
temp.pop_back();
}
}
}
}
}
//}
int main()
{int n=8;
p(0,n);printf("%d",a.size());
}