HZNU-ACM寒假集训Day3小结 搜索
简单搜索
1.DFS
UVA 548 树
1.可以用数组方式实现二叉树,在申请结点时仍用“动态化静态”的思想,写newnode函数
2.给定二叉树的中序遍历和后序遍历,可以构造出这棵二叉树,方法是根据后序遍历找到根,然后在中序遍历中找到树根,从而找出左右子树的结点列表然后递归 构造左右子树
3.注意这里输入的模板,用stringstream会方便
#include<iostream>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#define INF 0x3f3f3f3f
const int maxn = 1e6 + ;
const double PI = acos(-1.0);
typedef long long ll;
using namespace std; const int maxv = + ;
int in_order[maxv], post_order[maxv], lch[maxv], rch[maxv];
int n; bool read_list(int* a) {
string line;
if (!getline(cin, line)) return false;
stringstream ss(line);
n = ;
int x;
while (ss >> x) a[n++] = x;
return n > ;
} int build(int L1, int R1, int L2, int R2) {
if (L1 > R1) return ;
int root = post_order[R2];
int p = L1;
while (in_order[p] != root) p++;
int cnt = p - L1;
lch[root] = build(L1, p - , L2, L2 + cnt - );
rch[root] = build(p + , R1, L2 + cnt, R2 - );
return root;
} int best, best_sum; void dfs(int u, int sum) {
sum += u;
if (!lch[u] && !rch[u]) {
if (sum < best_sum || (sum == best_sum && u < best)) {
best = u;
best_sum = sum;
}
}
if (lch[u]) dfs(lch[u], sum);
if (rch[u]) dfs(rch[u], sum);
} int main() {
while (read_list(in_order)) {
read_list(post_order);
build(, n - , , n - );
best_sum = ;
dfs(post_order[n - ], );
cout << best << "\n";
}
return ;
}
2000提高组-C 单词接龙
用substr判断能否接上
#include<iostream>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#define INF 0x3f3f3f3f
const int maxn = 1e6 + ;
const double PI = acos(-1.0);
typedef long long ll;
using namespace std; string s[];
int vis[];
int Max=-;
int n; void dfs(string x, int len) {
Max = max(Max, len);
for (int i = ; i <= n; i++) {
if (vis[i] == ) continue;
int l1 = x.length();
int l2 = s[i].length();
int p = ;
while (p < min(l1, l2))
if (x.substr(l1 - p) == s[i].substr(, p)) break; else p++;
if (p < min(l1, l2)) {
vis[i]++;
dfs(x.substr(,l1-p)+s[i], len + s[i].length()-p);
vis[i]--;
}
}
} int main() {
std::ios::sync_with_stdio();
cin.tie(); cin >> n;
for (int i = ; i <= n; i++) cin >> s[i];
cin >> s[];
s[] = "" + s[];
dfs(s[], s[].length());
cout << Max-;
return ;
}
回溯 N皇后问题 http://acm.hdu.edu.cn/showproblem.php?pid=2553
#include<iostream>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#define INF 0x3f3f3f3f
const int maxn = 1e6 + ;
const double PI = acos(-1.0);
typedef long long ll;
using namespace std; int x[], y[]; //x[i]为第i行所在的列
int n1, ans; bool place(int k) {
for (int i = ; i < k; i++) {
if (abs(x[i] - x[k]) == abs(i - k) || x[i] == x[k]) return false;
}
return true;
} //判断位置是否可行
void dfs(int a) { //遍历到a行,共n1行
if (a > n1) ans++; //已经放了n1个皇后
else {
for (int i = ; i <= n1; i++) {
x[a] = i;
if (place(a)) dfs(a + );
}
}
} int main() {
int n;
for (int i = ; i <= ; i++) {
ans = ;
n1 = i;
dfs();
y[i] = ans;
}
while (scanf("%d", &n), n) {
printf("%d\n", y[n]);
}
return ;
}
BFS
BFS通常用队列实现,开一个vis数组标记是否访问过

如Catch That Cow http://poj.org/problem?id=3278 如果用DFS会TLE,考虑DFS
#include<iostream>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#define INF 0x3f3f3f3f
const int maxn = 1e6 + ;
const double PI = acos(-1.0);
const int N = ;
typedef long long ll;
using namespace std; int n, k;
struct Node {
int x;
int step;
};
queue<Node> q;
int vis[N]; void bfs() {
int X, Step;
while (!q.empty()) {
Node Q = q.front();
q.pop();
X = Q.x;
Step = Q.step;
if (X == k) {
printf("%d", Step);
return;
}
if (X >= && (!vis[X - ])) {
Node p;
vis[X - ] = true;
p.x = X - ;
p.step = Step + ;
q.push(p);
}
if (X <= k && (!vis[X + ])) {
Node p;
vis[X + ] = true;
p.x = X + ;
p.step = Step + ;
q.push(p);
}
if (X <= k && (!vis[X * ])) {
Node p;
vis[X * ] = true;
p.x = X * ;
p.step = Step + ;
q.push(p);
}
}
} int main() {
scanf("%d%d", &n, &k);
Node NODE ;
NODE.x = n;
NODE.step = ;
q.push(NODE);
bfs();
return ;
}
回溯法一般是要找到一个(或者所有)满足约束的解(或者某种意义下的最优解),而状态空间搜索一般是要找到一个从初始状态到终止状态的路径
路径寻找问题可以归结为隐式图的遍历,它的任务是找到一条从初始状态到终止状态的最优路径,而不像回溯法那样找到一个符合某些条件的解。
八数码问题
#include<iostream>
#include<map>
#include<queue> using namespace std; queue<int>Q;
map<int,int>vis;//标记数组
map<int,int>step;//记录到这种状态的步数 int dir[][]={-,,,,,,,-};//上,右,下,左
int mat[][];
int state;//输入的初始状态
int r,c; void input()//输入数据并将矩阵转化为一个九位整数
{
int tmp=;
for(int i=;i<;i++)
for(int j=;j<;j++)
{
cin>>mat[i][j];
tmp=tmp*+mat[i][j];
}
state=tmp;
} bool can_move(int u,int d)//判断是否可以走
{
for(int i=;i>=;i--)//将整数变回矩阵才好判断
{
for(int j=;j>=;j--)
{
mat[i][j]=u%;
u/=;
if(mat[i][j]==)
{
r=i;
c=j;
}
}
}
//判断四个方向是否能走
if((d==&&r==)||(d==&&c==)||(d==&&r==)||(d==&&c==))
return ;
return ;
} int move_to(int u,int d)//返回从状态u走到的状态
{
int tmp=;
int nr=r+dir[d][];
int nc=c+dir[d][];
mat[r][c]=mat[nr][nc];
mat[nr][nc]=;
for(int i=;i<;i++)
{
for(int j=;j<;j++)
tmp=tmp*+mat[i][j];
}
return tmp;
} int bfs(int s)
{
Q.push(s);
vis[s]=;
step[s]=;
while(Q.size())
{
int u,v;
u=Q.front();
Q.pop();
if(u==)
return step[u];
for(int i=;i<;i++)
{
if(can_move(u,i))
{
v=move_to(u,i);
if(!vis[v])
{
vis[v]=;
step[v]=step[u]+;
Q.push(v);
}
}
}
}
return -;
} int main()
{
input();
int ans=bfs(state);
cout<<ans<<endl;
return ;
}
拓扑排序
不包含有向环的有向图称为有向无环图(DAG),如果图中存在有向环,则不存在拓扑排序
HZNU-ACM寒假集训Day3小结 搜索的更多相关文章
- 中南大学2019年ACM寒假集训前期训练题集(基础题)
先写一部分,持续到更新完. A: 寒衣调 Description 男从戎,女守家.一夜,狼烟四起,男战死沙场.从此一道黄泉,两地离别.最后,女终于在等待中老去逝去.逝去的最后是换尽一生等到的相逢和团圆 ...
- 2022寒假集训day3
day3:四道检测题,花了大半天时间. T1 子集和问题 问题描述 子集和问题的一个实例为<S,c>.其中S={x1,x2,-,xn}是一个正整数的集合,c是一个正整数.子集和问题判定是否 ...
- 中南大学2019年ACM寒假集训前期训练题集(入门题)
A: 漫无止境的八月 Description 又双叒叕开始漫无止境的八月了,阿虚突然问起长门在这些循环中团长哪几次扎起了马尾,他有多少次抓住了蝉等等问题,长门一共回复n个自然数,每个数均不超过1500 ...
- HZNU-ACM寒假集训Day8小结 最小生成树
最小生成树(无向图) Kruskal 给所有边按从小到大排序 形成环则不选择(利用并查集) P1546 最短网络 https://www.luogu.com.cn/problem/P1546 #i ...
- HZNU-ACM寒假集训Day1小结 STL 并查集
常用STL 1.优先队列 priority_queue 内部是用堆(heap)实现的 priority_queue<int> pq; 默认为一个“越小的整数优先级越低的优先队列” 对于一些 ...
- HZNU-ACM寒假集训Day12小结 数论入门 题解
算不出的等式 BJOI2012 看到这题 真没什么办法 无奈看题解 1.注意到p/q 联想到斜率 2.注意到 [ ] 联想到整点 注意到k在变化,构造一次函数 f(x)=p/q*x ,g(x)=q/p ...
- HZNU-ACM寒假集训Day12小结 数论入门
符号说明 a|b a整除b (a,b) a与b的最大公因数 [a,b] a与b的最小公倍数 pα||a pα|a但pα+1∤a a≡b(mod m) a与b对模m同余 a ...
- HZNU-ACM寒假集训Day11小结 贪心
1.刘汝佳紫书区间问题三大情况 1.选择不相交区间 贪心策略:一定要选择第一个区间 2.区间选点问题 贪心策略:取最后一个点 3.区间覆盖问题: n个闭区间,选择尽量少的区间覆盖一条指定线段[s,t] ...
- HZNU-ACM寒假集训Day10小结 单调栈-单调队列
数据结构往往可以在不改变主算法的前提下题高运行效率,具体做法可能千差万别,但思路却是有规律可循 经典问题:滑动窗口 单调队列O(n) POJ 2823 我开始写的: TLE 说明STL的库还是有点慢 ...
随机推荐
- ROS-4 : ROS节点和主题
依照<ROS-3 : Catkin工作空间和ROS功能包>,创建catkin工作空间,并在起src下创建功能包ros_demo_pkg,依赖项为roscpp.std_msgs.action ...
- navcat工具常用快捷键
navcat工具常用快捷键 ctrl + n: 打开新查询窗口 ctrl + shit + r: 只运行选中的语句 ctrl + /: 注释 (选中要注释的行,然后用快捷键注释) ctrl + sh ...
- arm linux 移植支持 HP打印机
背景 由于业务需要,需要hi3531d主板上加入对于HP打印机的支持. 通过与产品经理,技术主管的沟通:通用支持是不现实的,只要求彩色打印,先不考虑打印机的价格,只要支持一款打印机即可. 注意: Li ...
- java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver java.sql.SQLException
今天下午一直想用netbeans连接数据库,结果就是来来回回碰到这两个问题. 我还在想,连接数据库并不是一个什么困难的事情啊,我都按照教程上一步一步做的,代码什么的都感觉很好,怎么就找不到类呢,怎么就 ...
- helloctf.exe ----攻防世界
下载附件之后,查壳发现没有壳,运行试试看 很平常的输入代码,然后ida查看一下,开始就发现一个注意的地方,但是还是继续向下看, 结果就是CrackMeJustForFun
- Spring MVC RedirectAttributes取值方法
RedirectAttributes是Spring mvc 3.1版本之后出来的一个功能,专门用于重定向之后还能带参数跳转的他有两种带参的方式:第一种: attr.addAttribute(" ...
- 十五、React:简单点餐实例:知识点,html解析写法
一.功能 从首页列表点进去,转到详情页 列表.详情从Api获取 Api列表:http://a.itying.com/api/productlist 详情:http://a.itying.com/api ...
- 【学CG系列】web之审查元素
一.审查元素的作用 审查元素(你的F12)可以做到定位网页元素.实时监控网页元素属性变化的功能,可以及时调试.修改.定位.追踪检查.查看嵌套 ,修改样式和查看js动态输出信息,是开发人员得心应手的好工 ...
- java 根据值获取枚举对象
关键方法: /** * 值映射为枚举 * * @param enumClass 枚举类 * @param value 枚举值 * @param method 取值方法 * @param <E&g ...
- 解决Elasticsearch索引只读
今天添加索引时发现kibana添加索引不生效,页面也没有报错,没有创建成功只是一闪而过. 另外发现各项目日志与当前时间差异很大,filebeat一直报错io timeout 具体报错如下: fileb ...