搜索专题练习

T1:狗哥玩木棒

现给出一些木棒长度,那么狗哥能否用给出的木棒(木棒全用完)组成一个正方形呢?

思路:

既然已经规定木棒全都用上,那么边长就已经定下,就是周长的四分之一

那么只要考虑剪枝和细节模拟就好了

同时,我们对木棒进行排序,保证木棒长度有序,短的木棒可以对长的进行填充,进行极大的优化

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=25;
int n,m;
int a[N];
bool used[N],ok;
int sum;
inline void clear(){
	memset(used,0,sizeof used);
	sum=0;
	ok=0;
}
inline bool cmp(const int &a,const int &b){
	return a>b;
}
inline void search(int pos,int now){
	if(ok||now>sum) return ;
	if(now==sum) {now=0;++pos;}
	if(pos==4) {printf("yes\n");ok=1;}
	for(int i=1;i<=m;++i){
		if(!used[i]){
			used[i]=1;
			search(pos,now+a[i]);
			used[i]=0;
			if(!now||!(now+a[i])) return ;
		}
	}
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		clear();
		scanf("%d",&m);
		for(int i=1;i<=m;++i) {scanf("%d",&a[i]);sum+=a[i];}
		sum/=4;
		sort(a+1,a+1+m,cmp);
		search(0,0);
		if(!ok) printf("no\n");
	}
}

T2:骑马修栅栏

John 是一个与其他农民一样懒的人。他讨厌骑马,因此从来不两次经过一个栅栏。

John 的农场上一共有 m 个栅栏,每一个栅栏连接两个顶点,顶点用 1 到 500 标号(虽然有的农场并没有那么多个顶点)。一个顶点上至少连接 1 个栅栏,没有上限。两顶点间可能有多个栅栏。所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。John 能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束。

你需要求出输出骑马的路径(用路上依次经过的顶点号码表示),使每个栅栏都恰好被经过一次。如果存在多组可行的解,按照如下方式进行输出:如果把输出的路径看成是一个 500 进制的数,那么当存在多组解的情况下,输出 500 进制表示法中最小的一个 (也就是输出第一位较小的,如果还有多组解,输出第二位较小的,以此类推)。

输入数据保证至少有一个解。

思路:

考虑每个点与路径(栅栏)的联系,可以帮助处理题目

在这种"一笔画问题"中,统计"奇点数"是一种即为广泛的做法

结合代码理解:

#include<iostream>
#include<cstdio>
#define ci const int &
using namespace std;
const int N=505;
int n,cnt;
int f[N][N],in[N];
int rd[N];
int maxn;
inline void search(ci now){
	for(int i=1;i<=maxn;++i)
		if(f[now][i]) {--f[now][i]; --f[i][now]; search(i);}
	rd[++cnt]=now;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		int a,b;
		scanf("%d%d",&a,&b);
		++f[a][b]; ++f[b][a];
		++in[a]; ++in[b];
		maxn=max(max(a,b),maxn);
	} int s=1;
	for(int i=1;i<=maxn;++i){
		if(in[i]%2){
			s=i;
			break;
		}
	} search(s);
	for(int i=cnt;i>=1;--i)
		printf("%d\n",rd[i]);
	return 0;
}

原文地址:https://www.cnblogs.com/648-233/p/12678644.html

时间: 2024-11-25 12:52:43

搜索专题练习的相关文章

搜索专题小结及例题:POJ2251&amp;POJ1426&amp;POJ3087&amp;POJ2488

图的遍历也称为搜索,就是从图中某个顶点出发,沿着一些边遍历图中所有的顶点,且每个顶点仅被访问一次,遍历可采取两种不同的方式:深度优先搜索(DFS)和广度优先搜索(BFS). 1.DFS算法思想` 从顶点v出发深度遍历图G的算法 ① 访问v0顶点,置vis[v0]=1,搜索v0未被访问的邻接点w,若存在邻接点w,则dfs(w),直到到达所有邻接点都被访问过的顶点u为止,接着退回一步,看是否还有其他没有被访问的邻接点.如果有,则访问此顶点,进行前述类似的访问,如果没有,就在退回一步进行搜索,重复上述

搜索专题总结

搜索专题总结 第七章的例题做得差不多了,还有一道枚举二叉树和一道比较难的搜方块的没过,另外有一道火柴的用IDA*水过,并没有过大数据,由于这道可以用dancing links过,所以留着dancing links一坑.接下来总结下这章的收获,首先最重要的当然是不需要判重的高效率的IDA*以及估价函数的设计技巧:然后是bfs+hash写得更熟练了,如果hash需要erase那么就只能用指针版的,但是效率会很慢,否则就用数组版的. 做搜索题的几个要点: 1,估算最坏复杂度. 2,寻找合适的剪枝策略,

搜索专题

搜索专题 标签(空格分隔): ACM专题小结 搜索专题主要就是围绕dfs()和bfs(). 这两个函数其实不难,搜索可以解决很多最小路径,最少次数问题bfs()等问题 维数从一维到三维:主要抓住移动的方向的控制,以及对访问过的状态的标记,以免重复访问,重复访问一方面运行时间加长另一方面申请的空间也会无厘头的暴增. 曾经在刷一道题的时候,系统显示的使用空间远远大于定义变量的空间,一时间懵逼了,后来才发现是标记没处理好,导致了大量的重复访问. 还有一个要注意的地方就是队列的清空,或者在函数里面定义队

CSP2019突击训练(搜索专题)

专题一 简单搜索POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 FliptilePOJ 1426 Find The MultiplePOJ 3126 Prime PathPOJ 3087 Shuffle'm UpPOJ 3414 PotsFZU 2150 Fire GameUVA 11624 Fire!POJ 3984 迷宫问题HDU 1241 Oil DepositsHDU 1495 非常可乐HDU 261

‘简单’搜索专题总结

kuangbin专题一 A. 棋盘问题 在是棋盘的格子上放置棋子,其中要求所有棋子不同行也不同列,求摆放的方案数. dfs,参数:行.棋子数,遍历的时候要回溯. B. Dungeon Master 走迷宫,3D的走迷宫. C. Catch That Cow 最短时间找到那只牛. bfs,剪枝. D. FilpTile 翻方块,上一行状态决定下一行的翻转. E. Find The Multiple 大胆的bfs,数据范围很小的. F. Prime Path bfs G. Shuffle'm Up

记忆化搜索专题

Hdoj  1078 题目足迹 题意: n*n的矩阵,从(0,0)出发,每个点上有一个数值,每次只能水平或竖直的走至多k个格子,要求总的路线上的数值是严格单增的,并且使总的和最大. 代码: 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #define mem(a,b) memset(a,b,sizeof(a)) 6 #define for

搜索专题小结:迭代加深搜索

迭代加深搜索 迭代加深搜索(Iterative Deepening Depth-First Search, IDDFS)经常用于理论上解答树深度上没有上界的问题,这类问题通常要求出满足某些条件时的解即可.比如在"埃及分数"问题中要求将一个分数a/b分解成为若干个形如1/d的加数之和,而且加数越少越好,如果加数个数相同,那么最小的分数越大越好.下面总结一下该方法的一般流程: (1)概述:迭代加深搜索是通过限制每次dfs的最大深度进行的搜索.令maxd表示最大的搜索深度,那么dfs就只能在

poj 3126 Prime Path(搜索专题)

Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20237   Accepted: 11282 Description The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-di

搜索专题(不定期更新)

1.POJ 2386  Lake Counting 题意:给出一块区域,询问有多少个湖泊? 思路:DFS,对于'W',深搜一次,并标记已访问.之后每次对未访问的'W'做一次深搜. 1 #include<iostream> 2 #include<memory.h> 3 using namespace std; 4 char lake[105][105]; 5 bool vis[105][105]; 6 int n, m; 7 void DFS(int r, int c) 8 { 9

暴力搜索专题小结:全排列及可重集排列生成算法

1~n的全排列 (1)思路:按照递归的思想,初始化集合S中含有1~n所有元素.如果1~n的集合S为空,那么输出全排列:否则从小到大依次考虑每个元素i,在A的末尾添加i后,集合S变为S-{i}.这里我们不需要集合S,只需要利用一个变量cur表示当前位要填的数即可.那么A中没有出现过的元素均可以选择. #define N 100 int A[N]; void print_permutation(int n, int*A, int cur) { if (cur == n) { for (int i =