YbtOJ「基础算法」第4章 深度搜索

YbtOJ 大全

【例题1】拔河比赛

我们在 d f s dfs dfs 的过程中记录当前选了几个人,这些人的体重是多少,然后当遍历完所有人并且满足条件的时候,更新答案

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#define re register
#define drep(a,b,c) for(re int a(b) ; a>=(c) ; --a)
#define rep(a,b,c) 	for(re int a(b) ; a<=(c) ; ++a)
using namespace std;
inline int read(){
   
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){
   if(ch == '-') f=-1 ; ch=getchar();}
	while(ch>='0'&&ch<='9'){
   x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int M = 200;
int T,n,sum,ans = 1e9;
int a[M];
inline void dfs(int cur,int x,int tot){
   
	if(x == n/2){
   
		ans = min(ans,abs(tot*2-sum));
		return;
	}
	if(cur > n) return;
	dfs(cur+1,x+1,tot+a[cur]);
	dfs(cur+1,x,tot);
}
inline void work(){
   
	n = read();
	sum = 0,ans = 1e9;
	rep(i,1,n) a[i] = read(),sum += a[i];
	dfs(1,0,0);
	printf("%d\n",ans);
}
signed main(){
   
	T = read();
	while(T--) work();
	return 0;
}

【例题2】数独游戏

Y b t Ybt Ybt 书上讲的做法没看懂,就写了一个非常暴力的 d f s dfs dfs。用三个 v i s vis vis 数组分别记录行,列,宫是否有这个数字,在 d f s dfs dfs 的过程中判断是否可行,往下搜索即可。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#define re register
#define drep(a,b,c) for(re int a(b) ; a>=(c) ; --a)
#define rep(a,b,c) 	for(re int a(b) ; a<=(c) ; ++a)
using namespace std;
inline int read(){
   
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){
   if(ch == '-') f=-1 ; ch=getchar();}
	while(ch>='0'&&ch<='9'){
   x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int M = 10;
int a[M][M],vish[M][M],visl[M][M],vis[M][M];
int fl;
inline void pr(){
   
	rep(i,1,9) rep(j,1,9) printf("%d",a[i][j]);
	puts("");
}
inline void init(){
   
	memset(vish,0,sizeof(vish));
	memset(visl,0,sizeof(visl));
	memset(vis,0,sizeof(vis));
	memset(a,0,sizeof(a));
	fl = 0;
}
inline int pos(int x,int y){
   
	if(x <= 3 && y <= 3) return 1;
	if(x <= 3 && y <= 6) return 2;
	if(x <= 3 && y <= 9) return 3;
	if(x <= 6 && y <= 3) return 4;
	if(x <= 6 && y <= 6) return 5;
	if(x <= 6 && y <= 9) return 6;
	if(x <= 9 && y <= 3) return 7;
	if(x <= 9 && y <= 6) return 8;
	if(x <= 9 && y <= 9) return 9;
}
inline void dfs(int x,int y){
   
	if(fl == 1) return;
	if(x > 9) {
    pr(); fl = 1; return; }
	if(a[x][y] != 0){
   
		if(y == 9) dfs(x+1,1);
		else dfs(x,y+1);
	}
	else{
   
		int p = pos(x,y);
		rep(i,1,9){
   
			if(vish[x][i] || visl[y][i] || vis[p][i]) continue;
			vish[x][i] = visl[y][i] = vis[p][i] = 1;
			a[x][y] = i;
			if(y == 9) dfs(x+1,1);
			else dfs(x,y+1);
			vish[x][i] = visl[y][i] = vis[p][i] = 0;
			a[x][y] = 0;
		}
	}
}
signed main(){
   
	while(1){
   
		string s;
		cin >> s;
		if(s == "end") break;
		init();
		int l = 1,h &#
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值