摘要:
UVA_10603这个题目和普通的倒水问题不同的是,它不是去求最少的倒水次数,而是求最少的倒水量。普通倒水问题的解法可以参考刘汝佳白书P131。因而我们的判重的时候不能笼统地把所有重复的状态都抛弃,因为有些状态尽管是相同的,但倒水量却有可能不同。于是我们在判重之前,也应分析一下这个状态会不会对我们记录的达到某一水量时所需的倒水总量进行更新,如果进行了更新,那么即使状态与之前相同,我们也应把这个状态当作一个新的状态来处理。那么既然如果更新了记录即便是重复的状态也要当作新状态来处理,我们还有必要进行判重吗?实际上也存在着没有更新记录但确实是一个新状态的情况。 此外,在判重的时候运用了哈希的思想,由 阅读全文
摘要:
HDU_4023这个题目应该是一个博弈类的题目,既然是博弈,那么每一步就要为自己争取最大的利益或者为对方带来最大的损失,那么先放哪一个就要综合对自己的利益与对对方的损失来考虑。最后谁获得胜利只取决于Alice能走的步数是否比Bob多,同时这一因素又取决于两点:1.在双方都不能为对方带来损失时,谁是先手;2.双方还有多少个稳定的走位。所谓稳定的走位,就是不论对方如何走,都不会占去的但自己却随时可以走的位置。从上面分析的角度出发,我们可以把图分成下面5组:1.(1)(2)是一组,分别是Alice和Bob的稳定走位,所以可以放到最后去考虑。2.(15)单独为一组,综合来讲,(15)一旦放一个瓷砖,那 阅读全文
摘要:
UVA_10557这个题目实际上是求一个从起点到终点的最长路。但是由于路过每个点时权值都不能为负,所以我们在初始化距离数组d[]时要初始化0。之后就是用队列优化的Bellman-Ford算法去求最长路了,但是还有一些细节需要注意。我们当然可以在用这个算法时选择d[n]>0是就跳出循环来减少计算量,但也会找到使这个算法崩溃的例子,比如在某个位置存在一个正圈,而由这个正圈却不能到达终点,那么程序就会一直跑下去。但同样的,我们也不能见圈就跳,因为毕竟还是有些正圈可以到达终点的。这便要求我们去判断哪些正圈可以到达终点。于是我们可以选择在找最长路之前先做一下预处理,把所有能够到达终点的点找出来,一 阅读全文
摘要:
UVA_10004 对于这个题目,我们可以直接模拟染色的过程即可,如果发现要涂某一块时这个块已经被涂了色,并且与我们要使用的颜色不同的话,就说明这个图不能被染成BICOLORABLE的。#include<stdio.h>#include<string.h>int G[210][210],q[210],paint[210],n;int dfs(int u,int color){ int v; for(v=0;v<n;v++) if(G[u][v]) { if(paint[v]!=-1&&paint[v]!=color) ... 阅读全文
摘要:
UVA_10305 这个题目就是一个纯拓扑排序的问题,具体理论和代码可以参考刘汝佳白书P111。#include<stdio.h>#include<string.h>int n,st[110],top,G[110][110],vis[110];void dfs(int u){ int v; vis[u]=1; for(v=1;v<=n;v++) if(G[u][v]&&!vis[v]) dfs(v); st[--top]=u;}int main(){ int i,j,k,m,a,b; while(1) { ... 阅读全文
摘要:
UVA_10596这个题目就是一个纯欧拉回路的问题,具体理论可以参考刘汝佳白书P112,如果这个图是连通的,并且每个点只与偶数条路相连,那么一定存在欧拉回路。于是,我们只要去判断图是否连通,以及每个点所连的路的数量即可。一开始我没有注意存在R=0的情况,RE了很多次,而且R=0时一定要输出Not Possible,但不管怎么说,存在路的交点但不存在任何一条路确实是比较诡异的……#include<stdio.h>#include<string.h>int dgr[210],p[210];int find(int x){ return p[x]==x?x:(p[x]=fin 阅读全文
摘要:
UVA_10054这个题目实际上就是找一条欧拉回路并打印出路径即可,可以参考刘汝佳白书P112的代码,只要在这个代码的基础上稍作修改即可。当然,由于这个题目是无向图,我就直接反向打印的道路,如果是有向图的话,只要把printf改成压栈的操作即可,最后从栈顶开始依次输出(u,v)。#include<stdio.h>#include<string.h>int G[60][60],dgr[60],p[60];int find(int x){ return p[x]==x?x:(p[x]=find(p[x]));}int dfs(int u){ int v; for(v=1;v 阅读全文
摘要:
UVA_10129这个题目我一开始把一个字符串看成了一个点,这样就相当于去找是否存在一条不经过重复顶点的路径可以覆盖所有顶点,但这么去做的话会比较麻烦。后来想了一下,实际上可以把一个字符串看成一条有向边,26个字母是顶点,这样就转化成了找是否存在一条不经过重复边的路径可以覆盖所有的边,实际上就是找是否存在欧拉道路了。根据有向图的欧拉道路的结论(刘汝佳白书P112),首先,图必须是连通的,其次,最多只有两个点的入读不等于出度,而且必须是一个点的入读比出度大1,另一个点的出度比入读大1。为了保证图是连通的,我们可以在读入数据的时候用并查集进行操作。同时要记录下每个顶点的出入度,为后续的工作做准备。 阅读全文
摘要:
UVA_532 这个题目在一般图的遍历的基础上增加了一维,多了两个可以选择的方向。#include<stdio.h>#include<string.h>int a[40][40][40],vis[40][40][40];int qx[30000],qy[30000],ql[30000],dis[30000];int dx[]={-1,1,0,0},dy[]={0,0,-1,1};char b[40];int main(){ int i,j,k,L,R,C; int front,rear,newx,newy,newl,x,y,l; while(1) { sc... 阅读全文
摘要:
UVA_439 一个相对比较简单的搜索题,直接广搜即可。#include<stdio.h>#include<string.h>int a[10][10],qx[100],qy[100],vis[10][10];int dx[]={-2,-2,-1,1,2,2,1,-1};int dy[]={-1,1,2,2,1,-1,-2,-2};char b1[5],b2[5];int main(){ int i,j,k,ux,uy,vx,vy,front,rear,x,y,newx,newy; while(scanf("%s%s",b1,b2)!=EOF) { 阅读全文