kuangbin专题——简单搜索
A - 棋盘问题
题意
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
解法:n皇后的变形,注意放的位置不一定,并不是每一行都要放,计个step,然后dfs每一个点时,记得回溯上去处理一下,把vis[i]置为0,step--即可,然后处理完此次结束后,dfs(x+1),处理下一位;
#include<cstdio>
#include<cstring>
using namespace std;
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)k;i>=(int)j;i--)
int step,ans,n,k;
char mp[][];
bool vis[];
void dfs(int x){
if(step==k){
ans++;
return ;
}
if(x>=n)return ;
for(int i=;i<n;i++){
if(!vis[i]&&mp[x][i]=='#'){
step++;
vis[i]=;
dfs(x+);
vis[i]=;
step--;
}
}
dfs(x+);
}
int main(){
while(~scanf("%d %d",&n,&k)){
memset(vis,,sizeof vis);
if(n+k<)break;
rep(i,,n-){
scanf("%s",mp[i]);
}
ans=step=;
dfs();
printf("%d\n",ans); }
return ;
}
B - Dungeon Master
题意:就是个三维迷宫,直接广搜即可,用一个方向数组
#include<bits/stdc++.h>
#include<queue>
#include<cstring>
using namespace std;
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)k;i>=(int)j;i--)
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
const int maxn=1e5+;
bool isprime[maxn];
void makeprime(){
memset(isprime,true,sizeof isprime);
isprime[]=;
for(int i=;i*i<=maxn;i++){
if(isprime[i]==)continue;
for(int j=i*;j<=maxn;j+=i){
isprime[j]=;
}
}
// rep(i,1,maxn){
// cout<<i<<" "<<isprime[i]<<endl;
// }
}
struct point{int num,step;};
int ans,p,q;
bool vis[maxn];
bool bfs(){
memset(vis,,sizeof vis);
vis[p]=;
point tmp,next;
tmp.num=p,tmp.step=;
queue<point>Q;
Q.push(tmp);
while(!Q.empty()){
tmp=Q.front();
Q.pop();
vis[tmp.num]=;
if(tmp.num==q){
ans=tmp.step;
return true;
}
int t=tmp.num;
for(int i=;i<;i++){
for(int j=;j<=;j++){
t=tmp.num;
if(i==){
t-=t%;
t+=j;
}
else if(i==){
t-=t%/*;
t+=j*;
}
else if(i==){
t-=t%/*;
t+=j*;
}
else if(i==){
t-=t%/*;
t+=j*;
}
if(t==tmp.num||t<||vis[t]||!isprime[t])continue;
next.num=t,next.step=tmp.step+;
vis[t]=;
Q.push(next);
}
} }
return false;
}
int main(){
makeprime();
int cas;
scanf("%d",&cas);
while(cas--){
memset(vis,,sizeof vis);
scanf("%d %d",&p,&q);
ans=;
if(bfs())printf("%d\n",ans);
else printf("Impossible\n"); }
return ;
}
题意:给你n和m,问几步能走到,直接广搜即可
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)k;i>=(int)j;i--)
#define pb push_back
#define fi first
#define se second
#define check(x) (x<=N&&x>=0)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
const int N=1e5+;
bool vis[N];
int step[N];
int n,k;
void bfs(){
queue<int>Q;
vis[n]=;
step[n]=;
Q.push(n);
while(!Q.empty()){
int s=Q.front();
if(s==k)return ;
Q.pop();
if(check(s+)&&!vis[s+]){
vis[s+]=;
step[s+]=step[s]+;
Q.push(s+);
}
if(check(s-)&&!vis[s-]){
vis[s-]=;
step[s-]=step[s]+;
Q.push(s-);
}
if(check(s<<)&&!vis[s<<]){
vis[s<<]=;
step[s<<]=step[s]+;
Q.push(s<<);
}
}
}
int main(){
while(~scanf("%d%d",&n,&k)){
if(n>=k){
printf("%d\n",n-k);
}
else {
memset(vis,false,sizeof vis);
memset(step,,sizeof step);
bfs();
printf("%d\n",step[k]);
}
} return ;
}
D - Fliptile(学到许多)
题意: 给你一个01网格图,问你怎么按这些点,使得网格图全部置为0,找出字典序最小的方案;
解法: 这题用到二进制思想,解法就是枚举第一行的按键,然后剩下的每一行都可以由上一行递推而来;
递推公式为:press[i][j]=(mp[i-1][j]+press[i-1][j]+press[i-1][j+1]+press[i-2][j]+press[i-1][j-1])&1;
最后判断一下情况是否符合,即最后一行按键是否能全部熄灭,
这里我犯了一个错误,就是判断最后一行时没有按照递推公式算导致错误;
然后枚举第一行的按键用到了二进制,即枚举0<i<(1<<m),表示有m位二进制数,然后用位运算截取每一位数,即为 press[1][j]=(i>>(m-j))&1;
over
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int mp[][],ans[][],press[][];
int n,m;
const int inf=0x3f3f3f3f;
int guess(){ for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
press[i][j]=(mp[i-][j]+press[i-][j]+press[i-][j+]+press[i-][j]+press[i-][j-])&;
}
}
for(int j=;j<=m;j++){
if((press[n][j]+mp[n][j]+
press[n-][j]+press[n][j-]+press[n][j+])&!=)
return inf;
} int cnt=;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
cnt+=press[i][j];
}
} return cnt;
}
int main(){ while(~scanf("%d%d",&n,&m)){
memset(mp,,sizeof mp);
memset(ans,,sizeof ans);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
scanf("%d",&mp[i][j]);
int res=inf;
for(int i=;i<(<<m);i++){
memset(press,,sizeof press);
int test=;
for(int j=;j<=m;j++){
press[][j]=(i>>(m-j))&;
}
// cout<<"test:"<<i<<" "<<guess()<<endl;
// for(int i=1;i<=n;i++)
// for(int j=1;j<=m;j++)
// printf("%d%c",press[i][j],j==m?'\n':' '); int sum=guess();
if(res>sum){
res=sum;
memcpy(ans,press,sizeof press);
}
}
if(res==inf)printf("IMPOSSIBLE\n");
else {
// cout<<"test:"<<endl;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
printf("%d%c",ans[i][j],j==m?'\n':' '); }
}
return ;
}
E - Find The Multiple
题意:就是给你一个数,让你找它的一个只含01倍数的十进制数,
解法:直接深搜,但开始T了一发,没有做好剪树枝
计一个flag,如果搜到目标就停止;这样就能过了;
#include<cstdio>
using namespace std;
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)k;i>=(int)j;i--)
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
int n,flag;
ull ans;
void dfs(ull x,int step){
if(flag)return ;
if(x%n==){
flag=;
ans=x;
return ;
}
if(step==)return ;
dfs(x*+,step+);
dfs(x*,step+);
}
int main(){
// cout<<1000000000000000110%6<<endl;
while(~scanf("%d",&n),n){
ans=,flag=;
dfs(*1ll,);
printf("%lld\n",ans);
}
return ;
}
F - Prime Path
题意:就是给你两个素数,问你移动几步,使得由p走到q,而且每次移动只能变为素数,问你要变换几步;
解法:直接广搜即可;注意枚举每一位的情况;
#include<bits/stdc++.h>
#include<queue>
#include<cstring>
using namespace std;
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)k;i>=(int)j;i--)
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
const int maxn=1e5+;
bool isprime[maxn];
void makeprime(){
memset(isprime,true,sizeof isprime);
isprime[]=;
for(int i=;i*i<=maxn;i++){
if(isprime[i]==)continue;
for(int j=i*;j<=maxn;j+=i){
isprime[j]=;
}
}
// rep(i,1,maxn){
// cout<<i<<" "<<isprime[i]<<endl;
// }
}
struct point{int num,step;};
int ans,p,q;
bool vis[maxn];
bool bfs(){
memset(vis,,sizeof vis);
vis[p]=;
point tmp,next;
tmp.num=p,tmp.step=;
queue<point>Q;
Q.push(tmp);
while(!Q.empty()){
tmp=Q.front();
Q.pop();
vis[tmp.num]=;
if(tmp.num==q){
ans=tmp.step;
return true;
}
int t=tmp.num;
for(int i=;i<;i++){
for(int j=;j<=;j++){
t=tmp.num;
if(i==){
t-=t%;
t+=j;
}
else if(i==){
t-=t%/*;
t+=j*;
}
else if(i==){
t-=t%/*;
t+=j*;
}
else if(i==){
t-=t%/*;
t+=j*;
}
if(t==tmp.num||t<||vis[t]||!isprime[t])continue;
next.num=t,next.step=tmp.step+;
vis[t]=;
Q.push(next);
}
} }
return false;
}
int main(){
makeprime();
int cas;
scanf("%d",&cas);
while(cas--){
memset(vis,,sizeof vis);
scanf("%d %d",&p,&q);
ans=;
if(bfs())printf("%d\n",ans);
else printf("Impossible\n"); }
return ;
}
G - Shuffle'm Up
题意:就是给你两堆牌,问你怎么洗才能洗到目标状态,如果洗不到,输出-1;
解法:模拟洗牌的过程,如果洗到初始的状态,说明洗不到,
这里我犯了一个错误,就是在在下标里面写位运算会出错,也不知tmp[i*2]=s2[i];道为什么;
tmp[i*2]=s2[i]; 写成tmp【i>.>1】就不对了
#include<iostream>
#include<string>
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)k;i>=(int)j;i--)
using namespace std;
typedef long long ll;
string tmp,s1,s2,s12,goal;
int step,n,ans;
void bfs(){ s1=tmp.substr(,n);
s2=tmp.substr(n,n);
for(int i=;i<n;i++){
tmp[i*]=s2[i];
tmp[i*+]=s1[i];
}
step++;
if(tmp.compare(goal)==){
ans=step;
return ;
}
if(tmp.compare(s12)==){
ans=-;
return ;
}
bfs();
}
int main(){
int t,cas=;
// scanf("%d",&t);
cin>>t;
while(t--){
// scanf("%d",&n);
cin>>n>>s1>>s2>>goal;
tmp=s1+s2;
s12=tmp;
ans=step=;
bfs();
printf("%d %d\n",cas++,ans);
}
return ;
}
待更新;
PS:还是太菜了,要坚持刷题,写博客;
kuangbin专题——简单搜索的更多相关文章
- kuangbin专题简单搜索题目几道题目
1.POJ1321棋盘问题 Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形 ...
- [kuangbin带你飞]专题一 简单搜索 题解报告
又重头开始刷kuangbin,有些题用了和以前不一样的思路解决.全部题解如下 点击每道题的标题即可跳转至VJ题目页面. A-棋盘问题 棋子不能摆在相同行和相同列,所以我们可以依此枚举每一行,然后标记每 ...
- 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开
[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 这是一道经典的八数码问题.首先,简单介绍一下八数码问题: 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的 ...
- 简单搜索 kuangbin C D
C - Catch That Cow POJ - 3278 我心态崩了,现在来回顾很早之前写的简单搜索,好难啊,我怎么写不出来. 我开始把这个写成了dfs,还写搓了... 慢慢来吧. 这个题目很明显是 ...
- ElasticSearch 5学习(4)——简单搜索笔记
空搜索: GET /_search hits: total 总数 hits 前10条数据 hits 数组中的每个结果都包含_index._type和文档的_id字段,被加入到_source字段中这意味 ...
- nyoj 284 坦克大战 简单搜索
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=284 题意:在一个给定图中,铁墙,河流不可走,砖墙走的话,多花费时间1,问从起点到终点至少 ...
- 分布式搜索ElasticSearch构建集群与简单搜索实例应用
分布式搜索ElasticSearch构建集群与简单搜索实例应用 关于ElasticSearch不介绍了,直接说应用. 分布式ElasticSearch集群构建的方法. 1.通过在程序中创建一个嵌入es ...
- solr简单搜索案例
solr简单搜索案例 使用Solr实现电商网站中商品信息搜索功能,可以根据关键字搜索商品信息,根据商品分类.价格过滤搜索结果,也可以根据价格进行排序,实现分页. 架构分为: 1. solr服务器 2. ...
- 和我一起打造个简单搜索之SpringDataElasticSearch入门
网上大多通过 java 操作 es 使用的都是 TransportClient,而介绍使用 SpringDataElasticSearch 的文章相对比较少,笔者也是摸索了许久,接下来本文介绍 Spr ...
随机推荐
- python中软件开发规范,模块,序列化随笔
1.软件开发规范 首先: 当代码都存放在一个py文件中时会导致 1.不便于管理,修改,增加 2.可读性差 3.加载速度慢 划分文件1.启动文件(启动接口)--starts文件放bin文件里2.公共文件 ...
- Day5-T3
原题目 要开运动会了,神犇学校的n个班级要选班服,班服共有100种样式,编号1~100.现在每个班都挑出了一些样式待选,每个班最多有100个待选的样式.要求每个班最终选定一种样式作为班服,且该班的样式 ...
- C++远征--jame_yuan(慕课网)
int &a=b;引用符 int const a = 3; int *p = &a; 只读 不能 赋给 读写 有默认参数值得参数必须在参数表的最右端 void fun(int ...
- NIO组件Channel
基本介绍 NIO的通道类似于流, 但有些区别: 通道可以同时进行读写, 而流只能读或者只能写 通道可以实现异步读写数据 通道可以从缓冲区(Buffer)读数据, 也可以写数据到缓冲区 BIO中的str ...
- java 如何爬取百度百科词条内容(java如何使用webmagic爬取百度词条)
这是老师所布置的作业 说一下我这里的爬去并非能把百度词条上的内容一字不漏的取下来(而是它分享链接的一个主要内容概括...)(他的主要内容我爬不到 也不想去研究大家有好办法可以call me) 例如 互 ...
- sprintf与sscanf用法举例
一.sscanf 从tmp中读取a,b,c. int main(){ ]; int a; double b; ]; while(gets(tmp) != NULL){ sscanf(tmp, &quo ...
- uni-app实现弹窗遮罩
<template> <view> <view class="systemboxItem" @click="showSystemDialog ...
- HDU 5504:GT and sequence
GT and sequence Accepts: 95 Submissions: 1467 Time Limit: 2000/1000 MS (Java/Others) Memory Limi ...
- 用JS改变embed标签的src属性
思路: A.先隐藏embed标签 B.清除embed元素 C.为embed重新赋值,加入Html页面中 1.html代码 <object id="forfun" classi ...
- 安装python包的两种方法
1.在 anaconda 环境中安装包 selenium conda install selenium 2.python 下安装包 selenium pip install selenium 3.测试 ...