回溯法练习【BFS/DFS】
1.N皇后问题
2.油田问题
3.素数环问题
4.马踏棋盘问题
5.图的m着色问题
6.01背包问题
7.TSP问题
【Code-1:输出N皇后方案和个数】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 105;
const ll INF = 2147483647;
typedef pair<ll ,int> pli;
int a[maxn],b[maxn],c[maxn],mp[maxn][maxn];
int n,cnt;
void print()
{
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
printf("%d ",mp[i][j]);
printf("\n");
}
}
int dfs(int i)
{
for(int j=1;j<=n;j++)
{
if(!a[j] && !b[i-j+n] && !c[i+j])
{
mp[i][j]=i;
a[j]=b[i-j+n]=c[i+j]=1;
if(i==n)
{
print();
printf("\n");
cnt++;
}
else
{
dfs(i+1);
}
mp[i][j]=0;
a[j]=b[i-j+n]=c[i+j]=0;
}
}
}
int main()
{
scanf("%d",&n);
dfs(1);
printf("%d\n",cnt);
}
【HDU-2553-N皇后输出方案数/预处理打表】:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 105;
const ll INF = 2147483647;
typedef pair<ll ,int> pli;
int a[maxn];
int cnt=0;
int vis[3][maxn];
int n;
void dfs(int i)
{
if(i==n+1)
{
cnt++;
return ;
}
for(int j=1;j<=n;j++)
{
if(!vis[0][i-j+n] && !vis[1][j] && !vis[2][i+j])
{
vis[0][i-j+n] = vis[1][j] = vis[2][i+j] = 1;
dfs(i+1);
vis[0][i-j+n] = vis[1][j] = vis[2][i+j] = 0;
}
}
}
int main()
{
for(n=1;n<=10;n++)
{
memset(vis,0,sizeof(vis));
cnt=0;
dfs(1);
a[n]=cnt;
}
while(~scanf("%d",&n),n)
{
printf("%d\n",a[n]);
}
}
【Code-2】:HDU 1241
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 105;
const ll INF = 2147483647;
typedef pair<ll ,int> pli;
//int dir[8][2]={ {0,1},{1,-1},{-1,0},{-1,-1},{-1,0},{-1,1},{0,1},{1,1} };
int dir[8][2]={1,0,-1,0,0,1,0,-1,1,1,-1,-1,1,-1,-1,1};
char mp[maxn][maxn];
int n,m;
int ok(int x,int y)
{
if(x>=0 && y>=0 && x<n && y<m && mp[x][y]=='@')
return 1;
return 0;
}
void dfs(int x, int y)
{
mp[x][y]='*';//把找到的@变为*,以免重复搜索
for(int i=0;i<8;i++)
{
x=x+dir[i][0];
y=y+dir[i][1];
if(ok(x,y))
{
dfs(x,y);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m),n&&m)
{
//getchar();
int cnt=0;
for(int i=0;i<n;i++)
{
scanf("%s",mp[i]);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mp[i][j]=='@')
{
dfs(i,j);
cnt++;
}
}
}
printf("%d\n",cnt);
}
}
/*
5 5
****@
*@@*@
*@**@
@@@*@
@@**@
*/
【Code-3-素数环】:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 105;
const ll INF = 2147483647;
typedef pair<ll ,int> pli;
int n,cnt;
int vis[maxn];
bool isp(int n)
{
if(n<=1) return 0;
else
{
for(int i=2;i<=sqrt(n);i++)
{
if(n%i==0) return 0;
}
}
return 1;
}
int a[maxn];
/*
int print()
{
cnt++;
//printf("(%d)\n",cnt);
for(int j=1;j<=n;j++)
printf("%d ",a[j]);
printf("\n");
}
*/
void dfs(int cur)
{
if(cur>n && isp(a[1]+a[n]))
{
cnt++;
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
printf("\n");
}
else
{
for(int i=1;i<=n;i++)
{
if(vis[i]==0 && isp(i+a[cur-1]))
{
a[cur]=i;
vis[i]=1;
dfs(cur+1);
vis[i]=0;
}
}
}
}
int main()
{
scanf("%d",&n);
memset(a,0,sizeof(a));
dfs(1);
printf("Total sum is %d\n",cnt);
}
【Code-4-骑士周游】:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 50;
const ll INF = 2147483647;
typedef pair<ll ,int> pli;
int n,m;
int cnt;
int vis[maxn][maxn];
int fx[8]={-1,1,-2,2,-2,2,-1,1};
int fy[8]={-2,-2,-1,-1,1,1,2,2};
int a[maxn][maxn];
int f=0;
struct node
{
int x,y;
node(int a=0,int b=0):x(a),y(b){}
}path[maxn];
int ok(int x,int y)
{
if(x>=1 && y>=1 && x<=n && y<=m && !vis[x][y] && !f)
return 1;
return 0;
}
void print()
{
for(int i=1;i<=n*m;i++){
int x=path[i].x;
int y=path[i].y;
printf("%d %d\n",y,x); //输出坐标
}
}
void dfs(int x, int y, int d)
{
path[d]=node(x,y);
if(d==n*m)
{
f=1;
return ;
}
for(int i=0;i<8;i++)
{
int xx=x+fx[i];
int yy=y+fy[i];
if(ok(xx,yy))
{
vis[xx][yy]=1;
dfs(xx,yy,d+1);
vis[xx][yy]=0;
}
}
}
int main()
{
f=0;
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&m);
vis[1][1]=1;
dfs(1,1,1);
if(!f) puts("No");
else print();
}
【Code-5:洛谷-图的m着色问题】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 50;
const ll INF = 2147483647;
typedef pair<ll ,int> pli;
int n,m;
int a[maxn][maxn],c[maxn];
int sum=0;
int ok(int i)
{
for(int j=1;j<=n;j++)
{
if(a[i][j] && c[i]==c[j])
return 0;
}
return 1;
}
void dfs(int cur)
{
if(cur==n+1)
{
sum++;
for(int i=1;i<=n;i++)
printf("%d ",c[i]);
printf("\n");
return ;
}
else
{
for(int i=1;i<=m;i++)
{
c[cur]=i;
if(ok(cur))
{
dfs(cur+1);
}
c[cur]=0;
}
}
}
int main()
{
int x,y,k;
scanf("%d%d%d",&n,&k,&m);
while(k--)
{
scanf("%d%d",&x,&y);
a[x][y]=a[y][x]=1;
}
dfs(1);
if(!sum) puts("No");
else printf("%d\n",sum);
}
/*
5 8 4
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
48
*/
【Code6-01背包回溯版】:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2*1e5+5;
const ll INF = 2147483647;
typedef pair<ll ,int> pli;
//int v[maxn],w[maxn];
int n,c,cp,bestp;//物品数、背包大小、当前价值、最优价值
int x[maxn],bestx[maxn];//当前解、最优解
struct node
{
int v,w;//价值、重量
}a[maxn];
bool cmp(node a, node b)
{
return a.v*b.w > b.v*a.w;
}
void print()
{
for(int i=0;i<n;i++)
printf("%d ",bestx[i]);
printf("\n"); return ;
}
void dfs(int cur)
{
if(cur>=n)
{
if(bestp<cp)
bestp=cp;
for(int i=0;i<n;i++)
bestx[i]=x[i];
//print();
}
else
{
if(a[cur].w <= c)
{
x[cur]=1; cp+=a[cur].v; c-=a[cur].w;
dfs(cur+1);
x[cur]=0; c+=a[cur].w; cp-=a[cur].v;
}
x[cur]=0;
dfs(cur+1);
}
}
int main()
{
scanf("%d%d",&n,&c);
for(int i=0;i<n;i++)
scanf("%d",&a[i].v);
for(int i=0;i<n;i++)
scanf("%d",&a[i].w);
sort(a,a+n,cmp);
dfs(0);
printf("%d\n",bestp);
}
/*
5 10
6 3 6 5 4
2 2 4 6 5
最优价值 15
放入 1 2 3
3 30
16 10 13
45 20 25
*/
【输出路径版】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2*1e5+5;
const ll INF = 2147483647;
typedef pair<ll ,int> pli;
int w[maxn];
int v[maxn];
int best_ans[maxn], ans[maxn];
int cw, cv, n, max_w, max_v ;
void print()
{
printf("%d\n",max_v);
for(int i=0;i<n;i++)
printf("%d ",best_ans[i]);
printf("\n");
}
void DFS(int step,int cw,int cv)
{
if(step>=n)
{
if(cv > max_v)
{
max_v = cv;
for(int i=0;i<n;i++)
best_ans[i] = ans[i];
}
}
else
{
if(cw >= w[step])
{
ans[step] = 1; cv += v[step]; cw -= w[step];
DFS(step+1,cw,cv);
ans[step] = 0; cv -= v[step]; cw += w[step];
}
ans[step]=0;
DFS(step+1,cw,cv);
}
}
void init()
{
max_v = 0;
for(int i=0;i<n;i++)
ans[i] = 0;
max_v = 0;
}
int main()
{
while(scanf("%d%d",&n,&max_w)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%d",&v[i]);
for(int j=0;j<n;j++)
scanf("%d",&w[j]);
init();
DFS(0,max_w,0);
print();
}
return 0;
}
/*
5 10
6 3 6 5 4
2 2 4 6 5
*/
回溯法练习【BFS/DFS】的更多相关文章
- 『嗨威说』算法设计与分析 - 回溯法思想小结(USACO-cha1-sec1.5 Checker Challenge 八皇后升级版)
本文索引目录: 一.回溯算法的基本思想以及个人理解 二.“子集和”问题的解空间结构和约束函数 三.一道经典回溯法题点拨升华回溯法思想 四.结对编程情况 一.回溯算法的基本思想以及个人理解: 1.1 基 ...
- LeetCode刷题总结-DFS、BFS和回溯法篇
本文总结LeetCode上有关深度优先搜索(DFS).广度优先搜索(BFS)和回溯法的算法题,推荐刷题总数为13道.具体考点分析如下图: 一.深度优先搜索 1.字符匹配问题 题号:301. 删除无效的 ...
- UVA - 524 Prime Ring Problem(dfs回溯法)
UVA - 524 Prime Ring Problem Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & % ...
- P1378 油滴扩展 dfs回溯法
题目描述 在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界.必须等一个油滴扩展完毕才能放置下一个油滴. ...
- P1074 靶形数独 dfs回溯法
题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博士拿出了他最近发明的“靶 ...
- P1605 迷宫 dfs回溯法
题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫 中移动有上下 ...
- 回溯法、DFS
回溯法 为了求得问题的解,先选择某一种可能情况向前探索,在探索过程中,一旦发现原来的选择是错误的,就退回上一步重新选择条件,继续向前探索,如此反复进行,直至得到解或证明无解. DFS DFS模板 vo ...
- 剑指offer:矩阵中的路径(递归回溯法DFS类似迷宫)
1. 题目描述 /* 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径. 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子. 如果一条 ...
- 剑指offer:机器人的运动范围(回溯法DFS)
题目描述 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子. 例如,当k为18时,机器人能 ...
- POJ 2488 A Knight's Journey (回溯法 | DFS)
题目链接:http://poj.org/problem?id=2488 题意: 在国际象棋的题盘上有一个骑士,骑士只能走“日”,即站在某一个位置,它可以往周围八个满足条件的格子上跳跃,现在给你一个p ...
随机推荐
- P1196 [NOI2002]银河英雄传说
题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山压顶 ...
- [洛谷P3377]【模板】左偏树(可并堆)
题目大意:有$n$个数,$m$个操作: $1\;x\;y:$把第$x$个数和第$y$个数所在的小根堆合并 $2\;x:$输出第$x$个数所在的堆的最小值 题解:左偏树,保证每个的左儿子的距离大于右儿子 ...
- [NOIP2017 TG D2T2]宝藏
题目大意:给定一个有重边,边有权值的无向图.从某一个点出发,求到达所有的点需要的最少费用,并且限制两点之间只有一条路径.费用的计算公式为:所有边的费用之和.而边$x->y$的费用就为:$y$到初 ...
- wyh的天鹅~vector的使用
链接:https://www.nowcoder.com/acm/contest/93/L来源:牛客网 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 262144K,其他语言52428 ...
- 获取系统内RAR安装路径
RegistryKey the_Reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVers ...
- 获取html元素内容
html: <!DOCTYPE ><html> <head> <meta http-equiv="Content-Type" conten ...
- js中Date()对象详解
var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份(4位,1970-???? ...
- 用eval转化对象
var str = '{"name": "tom","age": 12,"sex": "man"}' ...
- MySQL中大于等于小于等于的写法
由于在mybatis框架的xml中<= , >=解析会出现问题,编译报错,所以需要转译 第一种写法: 原符号 < <= > >= & ' " 替换 ...
- Bzoj1692 洛谷P2870 [Usaco2007 Dec]队列变换
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1570 Solved: 656 Description FJ打算带他的N(1 <= N <= ...