$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$
随机推荐
- 从零学React Native之02状态机
本篇文章首发于简书 欢迎关注 之前我们介绍了RN相关的知识: 是时候了解React Native了 从零学React Native之01创建第一个程序 本篇文章主要介绍下下面的知识: 1.简单界面的搭 ...
- HZOJ 数颜色
一眼看去树套树啊,我可能是数据结构学傻了…… 是应该去学一下莫队进阶的东西了. 上面那个东西我没有打,所以这里没有代码,而且应该也不难理解吧. 这么多平衡树就算了,不过线段树还是挺好打的. 正解3: ...
- day6_python之json序列化和反序列化
json作用:用来保存当前状态 1.使用json.dumps序列化把dic字典存到文件中 dic={'name':'egon','age':18} print(json.dumps(dic)) #得到 ...
- @noi.ac - 508@ 01背包
目录 @description@ @solution@ @accepted code@ @details@ @description@ 有一天你学了一个能解决01背包问题的算法,你决定将这个算法应用到 ...
- 最适合 Python 入门的资源有哪些?
https://blog.csdn.net/zV3e189oS5c0tSknrBCL/article/details/81230593 学习任何一门编程语言或者技能基本上都遵循3个步骤,第一步是看,第 ...
- JS iFrame 加载慢怎么解决
在项目中经常要动态添加iframe,然后再对添加的iframe进行相关操作,有时候会遇到iframe加载很慢什么原因呢,该如何解决呢?带着这个问题一起通过本文学习,寻找答案吧! aaa.html &l ...
- Android本地数据存储: Reservoir
一:前言 今天做项目,准备使用本地存储,把一些数据存在本地磁盘上,比如用户名.密码这样的.其实大家都知道,这种情况最常用的就是SharedPreferences了,我也不例外,脑子里第一个想到的就是用 ...
- uva 100 The 3n + 1 problem (RMQ)
uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem= ...
- codeforces1238-div2
C 目前在h的高度,1~h每一个台阶要么处于out的状态,要么处于in的状态,问最少改变几个台阶的状态,使得能够从h的高度到0. 下降的唯一的方式,拉动lever,h-1的状态取反,下落的最大的高度不 ...
- hibernate无限递归问题
项目异常如下: 2018-01-26 17:12:38.162 WARN 3128 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionReso ...