ACM寒假培训5

学习总结

一.深度优先搜索DFS

注意点

1.用bool vis[ ]标记当前是否走过

2.停止条件

3.边界函数

4.递归进行搜索

5.记得回溯,vis [ ] 变为false

二.广度优先搜索BFS

过程

1.dx[ ] ,dy[ ] 储存方向向量

2.vis[ ] 标记是否走过

3.用队列每一个元素作为起点

4.如果某个方向的下一个位置还没走过,那么就走到该位置,并记录,同时让该点入队,

用队列才能保证走最近的路线

解题思路及代码

洛谷P1256

1.输入字符串转数字

2.广度优先搜索

3.采用队列

AC代码

#include
using namespace std;
const int N=200;
int dtx[4]={-1,1,0,0};
int dty[4]={0,0,-1,1};
int n,m,dis[N][N],mapp[N][N];
bool vis[N][N];
char c;
queue >Q;
bool ava(int x,int y){
	return x>=1&&x<=n&&y>=1&&y<=m;
}
int main(){
	cin>>n>>m;
	scanf("%c",&c);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%c",&c); 
			mapp[i][j]=c-'0';
			if(mapp[i][j]==1){
                vis[i][j]=true;
				Q.push(make_pair(i,j));
			}
		}
		scanf("%c",&c);
	}
	while(!Q.empty()){
		int x=Q.front().first;
		int y=Q.front().second;
		Q.pop();
		int x1,y1;
		for(int i=0;i<4;i++){
		x1=x+dtx[i];
		y1=y+dty[i];
		if(ava(x1,y1)&&!vis[x1][y1]){
			vis[x1][y1]=true;
			dis[x1][y1]=dis[x][y]+1;
			Q.push(make_pair(x1,y1));
		}
	    }
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j

洛谷P1460

1.dfs两种情况(即选与不选)

2.动态数组记录

3.判断供需

AC代码

#include
using namespace std;
int v,g;
int need[26],cnt[26];
int feed[16][26];
vector vec;
vector ans;
bool ok(){
	for(int i=1;i<=v;i++){
		if(cnt[i]vec.size())
		   ans=vec;
		else if(ans.size()==vec.size()&&vecg){
		return;
	}
    vec.push_back(k);
	for(int i=1;i<=v;i++){
		cnt[i]+=feed[k][i];
	}
	dfs(k+1);
	vec.pop_back();
	for(int i=1;i<=v;i++)
	    cnt[i]-=feed[k][i];
	dfs(k+1);
}
int main(){
	cin>>v;
	for(int i=1;i<=v;i++){
	cin>>need[i];
	}
	cin>>g;
	for(int i=1;i<=g;i++){
		for(int j=1;j<=v;j++){
			cin>>feed[i][j];
		}
	}
	dfs(1);
	cout<

洛谷P3456

1.深度优先搜索

2.采用队列

3.在搜索中分三类讨论

AC代码

#include
using namespace std;
const int N=1002;
const int dx[]={0,1,0,-1,1,1,-1,-1};
const int dy[]={1,0,-1,0,1,-1,1,-1};
int n,a[N][N];
int rc,vc;
bool vis[N][N];
bool ava(int x,int y){
	return x>=1&&y>=1&&x<=n&&y<=n;
}
void dfs(int sx,int sy){
	bool isr=true;
	bool isv=true;
	queue >Q;
	vis[sx][sy]=true;
	Q.push(make_pair(sx,sy));
	while(!Q.empty()){
		int x=Q.front().first;
		int y=Q.front().second;
		Q.pop();
		for(int i=0;i<8;i++){
			int x1=x+dx[i];
			int y1=y+dy[i];
			if(ava(x1,y1)){
				if(a[x1][y1]==a[x][y]&&!vis[x1][y1]){
					vis[x1][y1]=true;
					Q.push(make_pair(x1,y1));
				}
				if(a[x1][y1]a[x][y]){
					isr=false;
				}
			}
		}
	}
	if(isr) rc++;
	if(isv) vc++; 
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>a[i][j];
		} 
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(!vis[i][j]){
				dfs(i,j);
			}
		}
	}
	cout<

洛谷P1219

直接打表

AC代码

#include
using namespace std;
int main()
{
	int n;
	cin>>n;
	if(n==6) 
	{
		puts("2 4 6 1 3 5");
		puts("3 6 2 5 1 4");
		puts("4 1 5 2 6 3");
		puts("4");
	}
	if(n==7)
	{
		puts("1 3 5 7 2 4 6");
		puts("1 4 7 3 6 2 5");
		puts("1 5 2 6 3 7 4");
		puts("40");
	}
	if(n==8)
	{
		puts("1 5 8 6 3 7 2 4");
		puts("1 6 8 3 7 4 2 5");
		puts("1 7 4 6 8 2 5 3");
		puts("92");
	}
	if(n==9)
	{
		puts("1 3 6 8 2 4 9 7 5");
		puts("1 3 7 2 8 5 9 4 6");
		puts("1 3 8 6 9 2 5 7 4");
		puts("352");
	}
	if(n==10)
	{
		puts("1 3 6 8 10 5 9 2 4 7");
		puts("1 3 6 9 7 10 4 2 5 8");
		puts("1 3 6 9 7 10 4 2 8 5");
		puts("724");
	}
	if(n==11)
	{
		puts("1 3 5 7 9 11 2 4 6 8 10");
		puts("1 3 6 9 2 8 11 4 7 5 10");
		puts("1 3 7 9 4 2 10 6 11 5 8");
		puts("2680");
	}
	if(n==12)
	{
		puts("1 3 5 8 10 12 6 11 2 7 9 4");
		puts("1 3 5 10 8 11 2 12 6 9 7 4");
		puts("1 3 5 10 8 11 2 12 7 9 4 6");
		puts("14200");
	}
	if(n==13)
	{
		puts("1 3 5 2 9 12 10 13 4 6 8 11 7");
		puts("1 3 5 7 9 11 13 2 4 6 8 10 12");
		puts("1 3 5 7 12 10 13 6 4 2 8 11 9");
		puts("73712");
	}
	return 0;
}

洛谷P2404

拆分进行dfs

AC代码

#include
using namespace std;
int n,a[1000]={1,1};
void dfs(int sum,int num){
	for(int i=a[num-1];i<=sum;i++){
		a[num]=i;
		sum-=i;
		if(sum==0&&num!=1){
			for(int j=1;j>n;
	dfs(n,1);
	return 0;
} 

洛谷P1162

1.从边缘0开始广搜

2.用数组记录是否联通

3.被记录直接退出dfs节省时间

AC代码

#include
using namespace std;
int dtx[4]={-1,1,0,0};
int dty[4]={0,0,-1,1};
int mapp[31][31],vis[31][31],n,a[31][31];
void dfs(int x,int y){
	int x1,y1;
	for(int i=0;i<4;i++){
		x1=x+dtx[i];
		y1=y+dty[i];
		if(x1>=1&&y1>=1&&x1<=n&&y1<=n&&mapp[x1][y1]!=1&&!vis[x1][y1]){
			vis[x1][y1]=true;
			if(a[x1][y1]==1) return;
			a[x1][y1]=1;
			dfs(x1,y1);
			vis[x1][y1]=false;
		}
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++) scanf("%d",&mapp[i][j]);
	}
	for(int i=1;i<=n;i++){
		if(mapp[i][1]==0&&a[i][1]!=1) dfs(i,1);
		if(mapp[i][n]==0&&a[i][n]!=1) dfs(i,n);
		if(mapp[n][i]==0&&a[n][i]!=1) dfs(n,i);
		if(mapp[1][i]==0&&a[1][i]!=1) dfs(1,i);
	}
	for(int i=2;i

你可能感兴趣的:(算法,笔记,深度优先,广度优先)