专栏文章

深搜题库

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqlcpuy
此快照首次捕获于
2025/12/04 06:41
3 个月前
此快照最后确认于
2025/12/04 06:41
3 个月前
查看原文

排列问题:

基本思路+代码:

CPP
#include <bits/stdc++.h>
using namespace std;
int n,r,a[11];
int ji[11];
void f(int x)
{
	if(x==r)//到达排列上线 
	{
		for(int i=1;i<=r;i++)//输出排列 
		{
			cout<<a[i]<<' ';
		}
		cout<<'\n';
		return;
	}
	for(int i=1;i<=n;i++)
	{
		if(ji[i]==0)//i数没用过才能执行 
		{
			ji[i]=1;//表示i数已经用过 
			a[x+1]=i;//记录i 
			f(x+1);//进入下一层 
			ji[i]=0;//return后恢复 
		}
	}
}
int main(){
	cin>>n>>r;
	f(0);
	return 0;
}

组合问题:

基本思路+代码:

CPP
#include <bits/stdc++.h>
using namespace std;
int n,r,a[11];
void f(int x,int st)//为从小到大排序,加上一个st,st=最近加入的数+1 
{
	if(x==r)
	{
		for(int i=1;i<=r;i++)
		{
			cout<<a[i]<<' ';
		}
		cout<<'\n';
		return;
	}
	for(int i=st;i<=n;i++)//从st开始,保证从小到大 
	{
		a[x+1]=i;//不需要数组记录,因为st可以保证不重复 
		f(x+1,i+1);
	}
}
int main(){
	cin>>n>>r;
	f(0,1);
	return 0;
}

进阶:素数圈

基本思路:

在加入a数组时就判断与前一个相加是否为素数, 在最后再判断a数组中第一个与最后一个相加是否为素数。
CPP
#include <bits/stdc++.h>
using namespace std;
int n,a[22],b[22];
int ji[22];
int pz(int x)//判断素数 是返回1,否返回2 
{
	if(x<2) return 0;
	for(int i=2;i<=x/i;i++)
	{
		if(x%i==0) return 0;
	}
	return 1;
}
void f(int x)
{
	if(x==n)
	{
		if(!pz(a[1]+a[n]))//判断a数组中第一个与最后一个相加是否为素数
		{
			return;
		}
		for(int i=1;i<=n;i++) 
		{
			cout<<a[i]<<' ';
		}
		cout<<'\n';
		return;
	}
	for(int i=2;i<=n;i++)//1不用再考虑 
	{
		if(ji[i]==0&&pz(a[x]+i))//判断与前一个相加是否为素数
		{
			ji[i]=1;
			a[x+1]=i;
			f(x+1);
			ji[i]=0;
		}
	}
}
int main(){
	cin>>n;
	ji[1]=1;//第一个数始终为"1" 
	a[1]=1;
	f(1);
	return 0;
}

迷宫问题

与宽搜的区别:
宽搜:最短路长多少/ 深搜:有多少条路径

【入门】迷宫路线问题

基本思路+代码:

CPP
#include <bits/stdc++.h>
using namespace std;
int n,s[11][11],cnt,ji[11][11];
int dx[]={-1,0,1,0,-1,1,-1,1},dy[]={0,-1,0,1,-1,1,1,-1};
void f(int px,int py)
{
	if(px==1&&py==n)//到达终点
	{
		cnt++;
		return;
	}
	for(int i=0;i<8;i++)//向8个方向走 
	{
		int nx=px+dx[i],ny=py+dy[i];
		if(nx<=n&&nx>0&&ny<=n&&ny>0&&s[nx][ny]==0&&ji[nx][ny]==0)//没出边界&&能走&&没走过(此条路径) 
		{
			ji[nx][ny]=1;//记录走过了 
			f(nx,ny);
			ji[nx][ny]=0;//还原 
		}
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)//输入 
	{
		for(int j=1;j<=n;j++)
		{
			cin>>s[i][j];
		}
	}
	ji[1][1]=1;//起点不能再走 
	f(1,1);
	cout<<cnt;
}

N皇后

基本思路+代码:

CPP
#include <bits/stdc++.h>
using namespace std;
int n,cnt;
int row[15],col[15],v1[30],v2[30];
void f(int l){
	if(l==n)
	{
		cnt++;
		if(cnt>3) return;
		for(int i=0;i<l;i++)
		{
			cout<<row[i]<<' ';//输出每行的皇后位置 
		}
		cout<<'\n';
		return;
	}
	for(int i=1;i<=n;i++)
	{
		if(!col[i]&&!v1[i+l]&&!v2[i-l+n])
		{
			row[l]=i;//行记录 
			col[i]=1;//列记录 
			v1[i+l]=1;//对角线1记录 
			v2[i-l+n]=1;//对角线2记录
			f(l+1);
			col[i]=0;//列还原
			v1[i+l]=0;//对角线1还原
			v2[i-l+n]=0;//对角线2还原
		}
	}
}
int main(){
	cin>>n;
	f(0);
	cout<<cnt;
	return 0;
}

取数游戏

基本思路+代码:

CPP
#include <bits/stdc++.h>
using namespace std;
const int N=10;
int T,n,m,a[N][N],s[N][N],mx=-1e9;
void f(int x,int y,int sum)
{
	mx=max(mx,sum);//每次判断一下 
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if((i>x||i==x&&j>y)&&s[i][j]==0)//该位置在上一个位置后面&&能走 
			{
				for(int k=i-1;k<=i+1;k++)
					for(int l=j-1;l<=j+1;l++)
						s[k][l]++;//记录不能再取的位置 
				f(i,j,sum+a[i][j]);
				for(int k=i-1;k<=i+1;k++)
					for(int l=j-1;l<=j+1;l++)
						s[k][l]--;//坑!不是s[k][l]=0
			}
		}
	}
}
int main(){
	cin>>T;
	while(T--)
	{
		mx=-1e9;//初始化 
		cin>>n>>m;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				cin>>a[i][j];
			}
		}
		f(0,0,0);
		cout<<mx<<'\n';
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...