$vjudge-$搜索专题题解
退役了,刷点儿无脑水题$bushi$放松下$QwQ$
然后先放个链接,,,$QwQ$
$A$
虽然是英文但并不难$get$题目大意?就说给定一个数独要求解出来,$over$
昂显然直接$dfs$加剪枝就成?显然就是个考剪枝技巧的题呗$QwQ$
首先显然在$dfs$的过程中每次一定是找到可能的取值最少的那个格子填?
然后考虑怎么记录每个格子的取值数量?
昂可以考虑给每行每列每个九宫格分别开个二进制数存哪些数被用了,然后对每个格子就把它这行这列这九宫格或起来,剩下的就是能用的了$QwQ$.而且因为是个$dfs$所以可以设成全局变量$QwQ$
$over$
还有一个方法是$dlx$,老年退役选手不配拥有脑子不想学不写了$QwQ$
阿还有就我没想到很好的方法找可能的取值最少的格子,,,所以我决定先不写,,,发现能过于是就不写了$QwQQQQQ$
然后因为我是用$lowbit$找可能取值,所以找到的都是1嘛,所以在这题里面我都是1表示还没用0表示用了$QwQ$
#include<iomanip>
#include<cstdio>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define lowbit(x) (x&(-x))
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i) const int N=;
int a[N][N],h[N],l[N],gz[N],tot=(<<)-;
bool flg;
char str[N];
map<int,int>mapp; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il int nam(ri i,ri j){return ((i-)/*+(j-)/)+;}
il void dfs(ri x,ri y)
{
if(y>)++x,y=;
if(flg || x>)return void(flg=);
if(a[x][y]>)return void(dfs(x,y+));
ri nw=h[x]&l[y]&gz[nam(x,y)];
while(nw)
{
ri tmp=lowbit(nw);
a[x][y]=tmp;h[x]-=tmp;l[y]-=tmp;gz[nam(x,y)]-=tmp;dfs(x,y+);if(flg)return;
h[x]+=tmp;l[y]+=tmp;gz[nam(x,y)]+=tmp;a[x][y]=;nw-=tmp;
}
} int main()
{
//freopen("A.in","r",stdin);freopen("A.out","w",stdout);
ri T=read();rp(i,,)mapp[<<i]=i;
while(T--)
{
rp(i,,)h[i]=l[i]=gz[i]=tot;
rp(i,,)
{
scanf("%s",str+);
rp(j,,)
{
a[i][j]=(<<(str[j]^''))/*;//if(a[i][j]<2)a[i][j]=0;
h[i]-=a[i][j],l[j]-=a[i][j],gz[nam(i,j)]-=a[i][j];//,printf("%d:(%d,%d)\n",nam(i,j),i,j);
}
}
flg=;dfs(,);
rp(i,,){rp(j,,)printf("%d",mapp[a[i][j]]);printf("\n");}
}
return ;
}
$B$
基本想法很$easy$咯,直接枚举长度然后$dfs$康康能不能拼出来,$over$
前面几题都在于剪枝?说说这题怎么剪枝嗷$QwQ$
首先显然长的先安排,不会证但感性理解十分显然昂$QwQ$
然后对于当前原始木棒,记录最近一次拼接的木棒长度,如果布星相同长度的就都可以弃了$QwQ$
第三个是如果存在某根木棒放入的第一根就布星就直接返回$false$,因为这些空木棒是等效的,如果这根木棍不能放入这根就一定都布星.
最后是如果某根木棒在放入一根木棍后拼凑成功了,但是之后搜索的时候发现后面的无法拼凑成功,就布星直接返回$false$.十分显然?就因为是从长到短放的,所以如果继续搜索下去就是用几根短木棍替代这根木棍,显然更劣$QwQ$
$over$
然后我依然打了个错误的$dfs$,,,就我开始想的是一根根木棍地安排,但感性理解下发现显然安排木棒的复杂度会低些,所以应该要从木棒入手,,,不然会$T$,,,不要问我怎么知道的$QAQ$
#include<algorithm>
#include<iomanip>
#include<cstdio>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define lowbit(x) (x&(-x))
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i) const int N=;
int n,a[N],sum,len,cnt,stck[N],val;
bool gdgs=,flg; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il bool cmp(ri gd,ri gs){return gd>gs;}
void dfs(ri num)
{
//printf("num=%d cnt=%d anum=%d\n",num,cnt,a[num]);
if(flg)return;if(cnt>sum/len)return;if(num>n)return void(flg=);
rp(i,,cnt)
{
if(stck[i]+a[num]<=len)
{stck[i]+=a[num];dfs(num+);stck[i]-=a[num];if(flg)return;if(stck[i]+a[num]==len)return;}
}
stck[++cnt]=a[num];dfs(num+);--cnt;
} int main()
{
//freopen("B.in","r",stdin);freopen("B.out","w",stdout);
while(gdgs)
{
n=read();val=;sum=;if(!n)return ;rp(i,,n)sum+=a[i]=read(),val=max(val,a[i]);sort(a+,a++n,cmp);
rp(i,val,sum)if(!(sum%i)){len=i;cnt=;flg=;dfs();if(flg)printf("%d\n",len),i=sum+;}
//len=40;cnt=0;flg=0;dfs(1);printf("flg=%d\n",flg);
}
return ;
}先放个会$T$的$code$
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define lowbit(x) (x&(-x))
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i) const int N=;
int n,a[N],sum,len,val;
bool gdgs=,flg,vis[N]; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il bool cmp(ri gd,ri gs){return gd>gs;}
void dfs(ri stck_len,ri num,ri cnt)
{
if(cnt>sum/len)return void(flg=);
if(stck_len==len)return void(dfs(,,cnt+));
ri pre=;
rp(i,num,n)
if(!vis[i] && a[i]!=pre && stck_len+a[i]<=len)
{
vis[i]=;dfs(stck_len+a[i],i+,cnt);if(flg)return;
pre=a[i];vis[i]=;if(num==)return;if(stck_len+a[i]==len)return;
}
} int main()
{
//freopen("B.in","r",stdin);freopen("B.out","w",stdout);
while(gdgs)
{
memset(vis,,sizeof(vis));val=;sum=;flg=;
n=read();if(!n)return ;rp(i,,n)sum+=a[i]=read(),val=max(val,a[i]);sort(a+,a++n,cmp);
rp(i,val,sum/)if(!(sum%i)){len=i;dfs(,,);if(flg)printf("%d\n",len),i=sum+;}
if(!flg)printf("%d\n",sum);
}
return ;
}
$C$
没看懂题先咕了$QwQ$
$D$
$16\times 16$看起来就很$dlx$,,,都要退役了我就不给自己找麻烦了懒得写了$QwQ$
$E$
开始想法是广搜,因为感觉长得就很$bfs$的样子?
但是这里广搜要注意下细节昂$QwQ$,就在$queue$里面不能只存一个数,,,$umm$说不清我直接把我反面教材先放上来趴$QwQ$.然后错在哪儿其实还挺显然不说了,没$get$的自己输下样例就发现问题了$QwQ$
#include<iomanip>
#include<cstdio>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i) const int N=+;
bool gdgs=;
int pre[N],que[N],cnt,n; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il void bfs()
{
queue<int>Q;Q.push();
while(!Q.empty())
{
ri nw=Q.front();que[++cnt]=nw;Q.pop();
rp(i,,cnt){ri tmp=nw+que[i];if(tmp<=n)if(!pre[tmp]){pre[tmp]=nw,Q.push(tmp);if(tmp==n)return;}}
}
}
void print(ri x){if(x==)return void(printf("%d ",x));print(pre[x]);printf("%d ",x);if(x==n)printf("\n");} int main()
{
freopen("E.in","r",stdin);freopen("E.out","w",stdout);
n=;memset(pre,,sizeof(pre));cnt=;bfs();
while(gdgs){n=read();if(!n)return ;print(n);}
return ;
}所以反正就发现如果广搜要记录所有路径,就不可做了
所以考虑用$idfs$,即迭代加深
迭代加深不难就不说了$QwQ$,直接放代码趴$QwQ$
#include<iomanip>
#include<cstdio>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i) const int N=+;
bool gdgs=,vis[N];
int a[N],n,dep;
bool flg; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
void dfs(ri num)
{
if(num>dep){if(a[dep]==n)flg=;return;}
memset(vis,,sizeof(vis));
my(i,num-,)
my(j,num-,)
if(a[i]+a[j]>a[num-] && a[i]+a[j]<=n && !vis[a[i]+a[j]])
{vis[a[i]+a[j]]=,a[num]=a[i]+a[j];dfs(num+);if(flg)return;}
} int main()
{
//freopen("E.in","r",stdin);freopen("E.out","w",stdout);
while(gdgs)
{
n=read();if(!n)return ;if(n==){printf("1\n");continue;}flg=;a[]=;dep=;
while(!flg){++dep;dfs();if(flg){rp(i,,dep)printf("%d ",a[i]);printf("\n");}}
}
return ;
}
$F$
感$jio$是道无脑$bfs$,,,但是码量似乎挺大的$QwQ$,,,,我我我我都要退役了就不给自己找麻烦了不做了$QwQQQQQ$
$G$
同上$QwQQQQQ$
$H$
题目大意说有$n$个城市之间有$m$条双向路,每条路要耗费一定的油量,每个城市的油价固定且已给出.有$q$个询问,表示从城市$s$走到$e$,油箱的容量为$c$,求最小花费
阿感觉有点儿像网络流24题的汽车加油问题,,,?设$f_{i,j}$表示到达位置$i$油量为$j$的最小花费,然后每次就两个决策?加油或者继续走.跑个$dij$就好,$over$
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<queue>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define w(i) edge[i].wei
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt) const int N=+,M=+,Q=+,inf=1e9;
int n,m,q,p[N],head[N],ed_cnt,dis[N][Q];
bool vis[N][Q];
struct ed{int to,nxt,wei;}edge[M<<];
struct ques{int x,y,z,id,as;}qs[Q];
struct node{int pos,dis,f;}; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il bool operator < (node gd,node gs){return gd.dis>gs.dis;}
il void ad(ri x,ri y,ri z){edge[++ed_cnt]=(ed){x,head[y],z};head[y]=ed_cnt;}
il bool cmp(ques gd,ques gs){return gd.x<gs.x;}
il void dij(ri S,ri T,ri f)
{
memset(dis,,sizeof(dis));memset(vis,,sizeof(vis));priority_queue<node>Q;Q.push((node){S,,});dis[S][]=;
while(!Q.empty())
{
node nw=Q.top();Q.pop();ri nwp=nw.pos,nwf=nw.f,nwdis=nw.dis;if(vis[nwp][nwf])continue;
//printf("nw_pos=%d nw_f=%d nw_dis=%d\n",nwp,nwf,nwdis);
vis[nwp][nwf]=;if(nwp==T){printf("%d\n",nwdis);return;}
//printf(" ? f=%d nwf=%d vis=%d dis=%d p=%d dis=%d\n",f,nwf,vis[nwp][nwf],dis[nwp][nwf],p[nwp],dis[nwp][nwf+1]);
if(nwf+<=f && !vis[nwp][nwf+] && dis[nwp][nwf]+p[nwp]<dis[nwp][nwf+])
dis[nwp][nwf+]=dis[nwp][nwf]+p[nwp],Q.push((node){nwp,dis[nwp][nwf+],nwf+});
e(i,nwp)
{
if(nwf>=w(i))
if(!vis[t(i)][nwf-w(i)] && dis[t(i)][nwf-w(i)]>nwdis)
{
dis[t(i)][nwf-w(i)]=nwdis,Q.push((node){t(i),nwdis,nwf-w(i)});
//printf("t=%d dis=%d\n",t(i),nwdis);
}
}
}
printf("impossible\n");
} int main()
{
//freopen("H.in","r",stdin);freopen("H.out","w",stdout);
n=read();m=read();rp(i,,n-)p[i]=read();rp(i,,m){ri x=read(),y=read(),z=read();ad(x,y,z);ad(y,x,z);}q=read();
while(q--){ri x=read(),y=read(),z=read();dij(y,z,x);}
return ;
}
$I$
题目大意就说给个图求$K$短路$QwQ$?
关于$K$短路,因为要退役了也懒得写学习笔记了$QwQ$,就只大概港下$QwQ$
常见方法就跑个$spfa+A*$(其实是个假算法,,,,$QwQ$不过操过这道题还是欧克的了$w$),然后$A*$的评估函数就$f(x)=dis_x+g_x$,$dis$就当前点到起点的距离,$g_x$就当前点到终点的距离.
然后答案的话,当一个节点第$K$次出队时,答案是它的优先级;当终点第$K$次出队时,答案是它的路程
$over$?
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<queue>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define w(i) edge[i].wei
#define tt(i) edget[i].to
#define wt(i) edget[i].wei
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
#define et(i,x) for(ri i=headt[x];i;i=edget[i].nxt) const int N=+,M=+;
int n,m,S,T,K,head[N],ed_cnt,dis[N],vis[N],edt_cnt,headt[N];
struct ed{int to,nxt,wei;}edge[M<<],edget[M<<];
struct node{int f,g,pos;}; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il bool operator < (node gd,node gs){return gd.f>gs.f;}
il void ad(ri x,ri y,ri z){edge[++ed_cnt]=(ed){x,head[y],z};head[y]=ed_cnt;}
il void adt(ri x,ri y,ri z){edget[++edt_cnt]=(ed){x,headt[y],z};headt[y]=edt_cnt;}
il void spfa(ri T)
{
queue<int>Q;memset(dis,,sizeof(dis));dis[T]=;vis[T]=;Q.push(T);
while(!Q.empty())
{
ri nw=Q.front();Q.pop();vis[nw]=;
et(i,nw)if(dis[tt(i)]>dis[nw]+wt(i)){dis[tt(i)]=dis[nw]+wt(i);if(!vis[tt(i)])vis[tt(i)]=,Q.push(tt(i));}
}
}
il int solv(ri S,ri T)
{
priority_queue<node>Q;if(dis[S]==dis[])return -;memset(vis,,sizeof(vis));Q.push((node){dis[S],,S});
while(!Q.empty())
{
node nw=Q.top();Q.pop();ri nwf=nw.f,nwg=nw.g,nwp=nw.pos;++vis[nwp];
if(vis[T]==K)return nwf;if(vis[nwp]>K)continue;
e(i,nwp)if(vis[t(i)]<K)Q.push((node){dis[t(i)]+nwg+w(i),nwg+w(i),t(i)});
}
return -;
} int main()
{
freopen("I.in","r",stdin);freopen("I.out","w",stdout);
n=read();m=read();rp(i,,m){ri x=read(),y=read(),z=read();ad(y,x,z);adt(x,y,z);}S=read();T=read();K=read();
spfa(T);if(S==T)++K;printf("%d\n",solv(S,T));
return ;
}
$J$
题目大意就是要解八数码问题,然后要求输出步骤$QwQ$
$bfs$就成?$QwQ$
如果不成我再来$upd$,,,?
$K$
$L$
随机推荐
- 操作SDO_GEOMETRY字段
读取SDO_GEOMETRY字段 select to_char(regexp_replace(sdo_util.to_gmlgeometry(t.intsxn_geom),'</?[^> ...
- 2019-8-31-dotnet-将文件删除到回收站
title author date CreateTime categories dotnet 将文件删除到回收站 lindexi 2019-08-31 16:55:58 +0800 2019-03-2 ...
- SuperSocket 服务管理器 (ServerManager)
什么 SuperSocket 服务管理器? SuperSocket 服务管理器是一个让你能够在客户中用图形化界面来管理和监控你的SuperSocket服务器程序的组件. 在服务器端配置服务器管理器 事 ...
- poj 3335 Rotating Scoreboard (Half Plane Intersection)
3335 -- Rotating Scoreboard 给出一个多边形,要求判断它的内核是否存在. 还是半平面交的题,在这道题中,公告板允许其所在位置与直线共线也算是可见,于是我们就可以将每一条直线微 ...
- 如何安装java环境和如何配置java环境
https://jingyan.baidu.com/article/0202781175839b1bcc9ce529.html java如今是一门十分热门的可跨平台面向对象的高级编程语言,那么作为学习 ...
- PHP redis安装扩展
命令: 查看php版本:PHP -v 查看php安装的扩展:PHP -m php扩展开发包(包括phpize,php -config):yum install php-devel which phpi ...
- SELinux: Could not downgrade policy file
在配置nfs服务器,设定selinux时,碰到了SELinux: Could not downgrade policy file的错误提示,下文是其解决方案. 一.故障现象 [root@system1 ...
- CentOS 安装 semanage 命令
CentOS 安装 semanage 命令 在服务器上运行: [root@ca1 ~]# yum install policycoreutils-python vim /etc/selinux/con ...
- uni-app学习记录04-轮播图和滑屏图片
<template> <view> <!-- 轮播图视图 swiper-item是每页的元素 --> <swiper :indicator-dots=&quo ...
- Python--day21--包
包: 包是一种通过使用‘.模块名’来组织python模块名称空间的方式. 1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高 ...