08 2011 档案
POJ 3080 Blue Jeans
摘要:POJ_3080这个题目直接暴力枚举就可以过了。一开始只看了Sample就开始做题了,结果忽视了输出的碱基至少要有3个这个条件。以后无论什么样的题目都要仔细审题!#include<stdio.h>#include<string.h>char b[15][70];char ans[70],temp[70];int main(){ int i,j,k,n,t,p,q,r,s,len,match,find,ok; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i 阅读全文
posted @ 2011-08-26 00:35 Staginner 阅读(259) 评论(0) 推荐(0)
POJ 2503 Babelfish
摘要:POJ_2503之前集训的时候做过这道题目的,这次想换个方法,但自己写的哈希函数毫不犹豫地挂掉了。于是重操旧刃,写了qsort+二分查找的代码。一定要找个时间系统学一下常见的哈希函数!#include<string.h>#include<stdlib.h>#include<stdio.h>char b[15],english[100010][15],other[100010][15];int r[100010];int cmp(const void *_p,const void *_q){ int *p=(int *)_p; int *q=(int *)_q 阅读全文
posted @ 2011-08-25 23:51 Staginner 阅读(263) 评论(0) 推荐(0)
POJ 1321 棋盘问题
摘要:POJ_1321 这个题目把棋子的坐标依次存进数组里,然后再分别用两个数组记录行和列有哪些已经被占用了,之后便从第一个棋子开始深搜即可,深搜函数带两个参数p,#include<stdio.h>#include<string.h>int qx[70],qy[70],visx[70],visy[70],m,k,ans;char b[70];void dfs(int p,int count){ int i; if(count==k) { ans++; return; } for(i=p;i<m;i++) if(!visx[qx[... 阅读全文
posted @ 2011-08-23 23:35 Staginner 阅读(329) 评论(0) 推荐(0)
POJ 3278 Catch That Cow
摘要:POJ_3278 这个是个比较简单的BFS的题目。#include<stdio.h>#include<string.h>int dis[200010],q[200010];int main(){ int i,j,N,K,front,rear,n,newn; while(scanf("%d%d",&N,&K)==2) { memset(dis,-1,sizeof(dis)); dis[N]=0; front=rear=0; q[rear++]=N; while(front<rear) { ... 阅读全文
posted @ 2011-08-23 02:44 Staginner 阅读(202) 评论(0) 推荐(0)
POJ 3009 Curling 2.0
摘要:POJ_3009一开始没有考虑周全,导致做这个题目的时候很是坎坷。首先,石头在移动的过程中,是可能在同一位置出现两次的,因而用vis[][]进行判重是不可取的,同时也正是基于这一点,用dis[][]去记录最短距离也同样是不可取的。其次,由于这个题目一次碰撞会让Block消失,因而会影响下面的操作,所以一般的BFS是行不通的。考虑到上面两点之后,便放弃BFS,而改用DFS。这个题目如果不限定解的深度而直接DFS会超时,所以在DFS过程中要限定解的深度在10及10以内。如果这个题目解的深度更深的话,还可以考虑用叠代加深的方式去DFS。#include<stdio.h>#include& 阅读全文
posted @ 2011-08-23 01:57 Staginner 阅读(366) 评论(0) 推荐(0)
POJ 2251 Dungeon Master
摘要:POJ_2251 这个题目相比之前做过的BFS遍历迷宫的问题,相当于增加了一维的空间,这样在移动的时候就多了两种选择。#include<stdio.h>#include<string.h>int a[35][35][35],dis[35][35][35],vis[35][35][35];int qx[27010],qy[27010],ql[27010];int dx[]={-1,1,0,0},dy[]={0,0,-1,1};char b[50];int main(){ int i,j,k,L,R,C,front,rear,sx,sy,sl,tx,ty,tl,l,x,y, 阅读全文
posted @ 2011-08-23 00:02 Staginner 阅读(200) 评论(0) 推荐(0)
POJ 2488 A Knight's Journey
摘要:POJ_2488又是一个骑士问题,果然在广搜中骑士问题是很经典的哈。这个题目比之间做过的骑士的问题实质上就是多了路径的打印,并且最后如果存在路径的话,路径要求是字典序最小的方案。做到字典序最小还是比较容易的,只要在dfs的时候按照从左到右,从上到下的顺序去dfs就可以了。我又一次把棋盘上的运算搞错了,以后一定要引起注意!上下移动对应x的减少与增加,左右移动对应着y的减少与增加!#include<stdio.h>#include<string.h>int vis[30][30],fax[30][30],fay[30][30],p,q,count,n;int ansx[30 阅读全文
posted @ 2011-08-22 23:09 Staginner 阅读(357) 评论(0) 推荐(0)
POJ 1915 Knight Moves
摘要:POJ_1915 这个题目跟POJ_2243是非常相似的,只不过棋盘的大小是变化的而已。在读起点与终点之后,只需要从起点开始,对周围8个可达的位置进行广搜并依次记录到达该位置时的步数,当搜到终点的时候退出循环即可。#include<stdio.h>#include<string.h>int vis[310][310],dis[310][310],qx[90010],qy[90010];int dx[]={1,2,2,1,-1,-2,-2,-1},dy[]={2,1,-1,-2,-2,-1,1,2};int main(){ int i,j,k,L,n,front,rear 阅读全文
posted @ 2011-08-22 20:53 Staginner 阅读(288) 评论(0) 推荐(0)
POJ 2243 Knight Moves
摘要:POJ_2243 在读入并转化起点与终点之后,只需要从起点开始,对周围8个可达的位置进行广搜并依次记录到达该位置时的步数,当搜到终点的时候退出循环即可。#include<stdio.h>#include<string.h>char s[5],t[5],sx,sy,tx,ty;int a[10][10],dis[10][10],qx[100],qy[100];int dx[]={-1,-2,-2,-1,1,2,2,1},dy[]={-2,-1,1,2,2,1,-1,-2};int main(){ int i,x,y,newx,newy,front,rear,min; wh 阅读全文
posted @ 2011-08-20 01:44 Staginner 阅读(229) 评论(0) 推荐(0)
POJ 3620 Avoid The Lakes
摘要:POJ_3620 只要顺序遍历每个格子,找到一个有水的格子后就以这个格子为起点进行深搜或者广搜即可,直到把连成片的有水的格子搜完即可,然后将搜到的有水的格子数与max进行比较,如果比max大则更新max的值。#include<stdio.h>#include<string.h>int a[110][110],sx[1010],sy[1010];int dx[]={-1,1,0,0},dy[]={0,0,-1,1};int main(){ int i,j,k,N,M,K,top,x,y,newx,newy,max,count; while(scanf("%d%d 阅读全文
posted @ 2011-08-20 00:53 Staginner 阅读(217) 评论(0) 推荐(0)
POJ 1088 滑雪
摘要:POJ_1088一开始没有什么思路,看了别人的代码后才发现原来这个题目就是一个动态规划的题目,主要的过程用记忆化递归来实现。在记录好各点的高度后,只需要依次枚举每个点,如果该点的dis[][]已被赋值,那么就直接将其与maxdis进行比较,之后maxdis更新为较大值,如果该点的dis[][]没有被赋值,那么就以该点为基础,向周围四个方向中可达的方向进行深搜,之后将dis[][]记录为这几个方向中的最大值+1,再将dis[][]的值与maxdis进行比较。#include<stdio.h>#include<string.h>int height[110][110],di 阅读全文
posted @ 2011-08-19 23:57 Staginner 阅读(257) 评论(0) 推荐(0)
POJ 2362 Square
摘要:POJ_2362 在有了POJ_1011的基础之后,这个题目还是能够比较轻松地独立完成的。#include<stdio.h>#include<string.h>#include<stdlib.h>int state[10010],st[10010],d,n,sum;int cmp(const void *_p,const void *_q){ int *p=(int *)_p; int *q=(int *)_q; return *q-*p; }int dfs(int rest,int complete,int start){ int i; if(rest== 阅读全文
posted @ 2011-08-17 22:23 Staginner 阅读(264) 评论(0) 推荐(0)
POJ 1011 Sticks
摘要:POJ_1011做完这个题目,让我不仅学到了一些别人剪枝的策略,更重要的是让我意识到了在搜索中剪枝的重要性。所谓剪枝,其实就是对程序的优化,尽可能地避免程序执行无用的操作。就这个题目而言,程序的优化主要有以下几个方面:①我们在拼木棒之前应该对木棒最长到短进行排序,这样方便我们后面挑选木棒的操作,因为如果前面先拼短木棒的话,很有可能后面任何一根木棒都不能填补剩余的长度,而先拼长木棒就可以在本来有解的情况下避免出现这种问题。②枚举拼好的木棒的长度时,枚举区间应在max(len)与sum/2之间,如果在这个区间内还没有找到解,那么最后的解只能是sum。③枚举的拼好的木棒的长度必须能够整除所有木棒长度 阅读全文
posted @ 2011-08-17 21:33 Staginner 阅读(559) 评论(3) 推荐(0)
POJ 1753 Flip Game
摘要:POJ_1753这个题目第一次看也确实没有什么思想,后来到网上看了一下“点灯游戏”的简介,也获得了不少的启发。这个题目关键的算法思想在于,对最少操作次数而言,由于每个棋子点击偶数次相当于没点,同时点击的顺序并不影响最终结果,所以每个棋子要么点击一次,要么干脆不点,理解了这一点之后思路便是大体形成了。于是把黑、白棋布局用1、0存储,再用一个4*4的数组和16层for循环来枚举操作的所有情况,之后一一计算每种操作是否能达到预期效果以及其所需的操作次数即可,所有的情况是2^16种,计算量还是可以接受的。(中间过了很多天……)时隔一个月之后,已经做完了八数码,便迫不及待的想找个题来巩固一下做八数码学到 阅读全文
posted @ 2011-08-17 02:04 Staginner 阅读(393) 评论(0) 推荐(0)
POJ 1077 Eight
摘要:POJ_1077经典的八数码问题,做完之后突然想到一句台词:“我的人生又趋于完整了一点……”。一开始接触这个确实觉得比较难,后来突然在刘汝佳书上发现原来是有讲这个问题的,于是我如获至宝,赶紧研究起刘汝佳的代码来,边学边写,总算是把代码写完了,同时又在他的代码和提示的基础上自己写了打印路径的方式。研究这个题的代码时,第一次比较认真地看了Hash的有关内容,掌握了一些基础的Hash判重的方法,同时对状态的表示也有了更深一步的理解,总之收获不菲呀。#include<stdio.h>#include<string.h>#define MAX 1000000#define HAS 阅读全文
posted @ 2011-08-17 00:22 Staginner 阅读(711) 评论(1) 推荐(1)
POJ 3169 Layout
摘要:POJ_3169这个题目和POJ 3159有点类似。首先我们要假定一个正向的顺序,比如规定牛从1至为正向排列,记d[i]为牛i距参照点的距离,那么对于ML的输入,有d[A]-d[B]>=-D,对于MD的输入有d[B]-d[A]>=D,前面的表达式中A都是小于B的。之后我一开始先是抽象出了一个源点0,并且d[i]-d[0]>=0,然后从0开始用SPFA判断是否有负圈,如果有负圈就输出“-1”。如果没有负圈,再从1开始用SPFA求至N的最短路,如果最后有最短路存在那么就输出d[N],否则1和N就可以离任意远的距离,则输出“-2”。虽然上面的代码AC了,但不够简洁。后来看了别人的报 阅读全文
posted @ 2011-08-15 23:17 Staginner 阅读(320) 评论(0) 推荐(0)
POJ 3159 Candies
摘要:POJ_3159 一开始我想多了,有段时间就在想如果图不连通该添加一些什么约束条件。但后来突然发现,如果最后N和1不连通的话,那么这个题就无解了,想到这,题目就变的简单了,因为只有一个约束条件,d[A]-d[B]>=-c,然后将d[1]看做0,以1为起点求一个到N的最短路就可以了。 此外,这个题在用SPFA的时候,如果用循环队列会超时,而用栈就没有问题,具体的原理我也不清楚。#include<stdio.h>#include<string.h>int first[31000],next[151000],v[151000],w[151000];int s[31000 阅读全文
posted @ 2011-08-15 20:56 Staginner 阅读(255) 评论(0) 推荐(0)
POJ 2983 Is the Information Reliable?
摘要:POJ_2983有了前面做的题目的基础后,这个题目也还算比较好想到的。我们设S[i]为点i到直线上某参照点的距离(可以把0看做这个参照点),为了写起来方面,干脆把题目A north thanB全部想像成B south than A,那么如果是输入P的时候,就应该有两个约束方程S[B]-S[A]>=X,S[A]-S[B]>=-X,而输入V的时候,就只对应着一个约束方程S[B]-S[A]>=1。之后如果用最短路去做的话,实际上就是判断这个图是否存在负圈。为了使图连通起来,我们抽象出一个源点0,则对任意点i都有S[i]-S[0]>=0,这样便将图连通了起来,最后只要以0为起点 阅读全文
posted @ 2011-08-15 19:31 Staginner 阅读(301) 评论(0) 推荐(0)
POJ 1716 Integer Intervals
摘要:POJ_1716 由于有了前面几个题目的基础,解答这个题目的过程还算顺利。我们设S[i]为区间[0,i)内选取的数字的数量,那么有①S[b+1]-S[a]>=2,②S[i+1]-S[i]>=0,③S[i]-S[i+1]>=-1。这样以max(b)+1为起点,以min(a)为终点求一个最短路就可以了,最后的结果为d[max(b)+1]-d[min(a)]。#include<stdio.h>#include<string.h>int first[10010],next[30010],v[30010],w[30010];int inq[10010],q[10 阅读全文
posted @ 2011-08-15 16:27 Staginner 阅读(350) 评论(0) 推荐(0)
POJ 1364 King
摘要:POJ_1364这个题目其实还算是比较简单的差分约束系统的题目。一开始其实已经把输入数据的约束条件都找全了,如果设S[i]为[a1,ai]的和,那么如果符号是gt,则有S[ai+ni]-S[ai-1]>=ki+1,如果符号是lt,则有S[ai-1]-S[ai+ni]>=-ki+1。然后发现这个图可能从S[n]开始做最短路不是连通的,于是我便想加两个辅助条件S[i]-S[i-1]>=-INF,S[i]-S[i-1]<=INF,这两个条件是没有问题的,但可能是由于INF精度的问题而WA掉了。后来再看了别人的报告之后,发现其实让图连通不用这么麻烦。首先,做最短路没必要把S[n 阅读全文
posted @ 2011-08-15 15:41 Staginner 阅读(382) 评论(0) 推荐(0)
POJ 1275 Cashier Employment
摘要:POJ_1275对差分约束系统还是有点摸不着头脑的感觉,看了别人的分析之后才把代码写了出来。首先这个题目可以做两个预处理,一个是在输入数据时找出R[i]的最大值,最后的结果一定是大于等于R[i]的,这样在枚举结果时就可以减少一部分工作量。另一个是在输入结束后,可以枚举8个小时的区间,如果这个区间里所有可雇用的人数加起来,还不足区间尾那个时间所需要的工人数,那么这种情况一定是无解的,反之,便一定是有解的。如果设S[i]为[0,i)这些时间内雇佣的总人数,那么可以列出下面几个差分约束方程:①S[i+1]-S[i]>=0;②S[i]-S[i+1]>=-t[i];③0<=j<= 阅读全文
posted @ 2011-08-15 02:48 Staginner 阅读(336) 评论(0) 推荐(0)
POJ 1201 Intervals
摘要:POJ_1201第一次接触差分约束系统的题目,有点摸不着头脑,看了别人的解析后又觉得差分约束系统也好神奇呵!假以时日,我一定会掌握它!我们设S[i]为区间[0,i)之内的Z元素的数量,那么根据输入可以构成一个约束条件S[b+1]-S[a]>=c,另外还有两个隐含条件,S[i+1]-S[i]>=0,S[i+1]-S[i]<=1,实际上还有另外一个条件S[b+1]-S[a]<=b+1-a,但这个条件可以由S[i+1]-S[i]<=1推导出来,所以就不必管它了。然后把上面3个条件变形后得到S[b+1]+(-c)>=S[a],S[i]+0<=S[i+1],S[ 阅读全文
posted @ 2011-08-14 18:13 Staginner 阅读(338) 评论(0) 推荐(0)
POJ 3177 Redundant Paths
摘要:POJ_3177说实话,我现在还是不明白这个题目究竟是想让我们如何去处理问题。首先的疑惑就是如果连续输入两个1 2,1和2之间算一条路还是两条路,其次如果分别输入1 2及2 1,这时1和2之间算一条路还是两条路?由于对上面数据的理解的不同,会用3种不同的处理方式:①不管1 2还是2 1,就当做是1和2之间连通,也就是完全忽略题目中所说的两点之间可以有多条路,多条时只当有一条。②两个1 2看做一条路,1 2及2 1看做两条路。③两个1 2看做两条路,1 2及2 1也看做两条路。其中根据①和②写出的程序都是可以AC的,而根据③写出的程序,依据我看到的一些讨论,应该是WA掉的。也正是因为这个,导致我 阅读全文
posted @ 2011-08-13 20:33 Staginner 阅读(273) 评论(0) 推荐(0)
POJ 3352 Road Construction
摘要:POJ_3352 这个题目和问最少添加多少条有向边使图成为一个强连通分量的题目有些类似,只不过题目的模型换成了边双连通分量的模型,我们同样可以用tarjan算法来解决,只不过相对于强连通分量的tarjan代码有稍许不同。由于题目中说明了各个点之间都是连通的,因而我们就不用再考虑孤立的点或者边双连通块了,只需要把最后的边双连通分量染色,求出各个所谓的是leaf的边双连通分量的个数,最后的答案就是(leaves+1)/2。所谓的“叶子”,就是针对一个边双连通分量来讲,它只和除自己之外的一个边双连通分量间存在一条无向边,那么这个边双连通分量就是所谓的“叶子”。至于最后的结果为什么是(leaves+1 阅读全文
posted @ 2011-08-13 17:15 Staginner 阅读(311) 评论(4) 推荐(0)
POJ 2553 The Bottom of a Graph
摘要:POJ_2553这个题目本来是比较容易下手的,最后只需要求所有出度为0的强连通分量所包含的点,然后按字典序输出即可。但是由于一开始用邻接表写代码的时候由于读入边和存储边的写法问题导致我一直TLE,后来终于知道了怎么写才不会TLE,但是还是不太懂其中的原理,听群里人说是因为TLE的写法翻译成汇编语言会多出很多语句。因此,以后写代码的时候,还是尽量少在数组名里面再嵌套数组名。同时看了别人的代码还有一些额外的收获,就是在用邻接矩阵储存无权边时,用bool数组要比int的效率高,数据多时,即使在C里面用char数组都要比int数组的效率有明显的提高(大概20%,当然只是针对这个题目而言)。#inclu 阅读全文
posted @ 2011-08-11 22:55 Staginner 阅读(457) 评论(0) 推荐(0)
POJ 2186 Popular Cows
摘要:POJ_2186 这个题目其实就是求完强连通分量之后,判断一下出度为0的强连通分量是否唯一,如果唯一输出该强连通分量的点数,否则输出0。由于之前求强连通分量的时候是把同一个强连通分量里的数放到一个数组里,然后枚举各个数组之间各元素是否有边来判断各个强连通分量是否连通,由于这样效率比较低,这次超时了。后来看了别人的代码后发现,其实可以找到强连通分量之后,把其中的每个元素都染成一个颜色(开一个数组paint[]来记录染色情况,颜色用num表示,初始化为0),最后枚举所有边,如果一条边(u,v)两个端点的颜色不一样,那么就让outdgr[paint[u]]++。当然,这样最后outdgr中存的并不是 阅读全文
posted @ 2011-08-11 19:27 Staginner 阅读(345) 评论(0) 推荐(0)
POJ 1236 Network of Schools
摘要:POJ_1236 这个题目的TaskA实际上就是在求入度为0的强连通分量的个数,而TaskB实际上就是在求各个强连通分量中入度为0的个数与出度为0的个数的较大值。 同时这个题目与之前做的点双连通的分量有所不同,其中有一点便是在求强连通分量时对于low[u]>dfn[v]时更新low[u]的值,有一个前提条件就是v在栈内,因而要单独用一个数组标记v是否在栈内,而求点双连通分量时则不需要这个数组,因为只要G[u][v]为1,且dfn[v]不为0,那么v一定在栈中。 对于双连通分量为什么不需要标记v是否在栈内,可以先假设v不在栈中但dfn[v]不为0,而如果G[u][v]为1,那么在dfs的过 阅读全文
posted @ 2011-08-11 17:56 Staginner 阅读(262) 评论(0) 推荐(0)
POJ 2942 Knights of the Round Table
摘要:POJ_2942说实话,这个题目对我来讲获益匪浅。一开始看了题目之后就没什么想法(而且后来在学习别人的代码时发现自己对题意的理解也有偏差),后来便去看别人的报告和代码,结果云里雾里,什么双连通、点双连通、边双连通、奇圈等等连概念甚至都不了解,一度令我很郁闷,但后来慢慢在纠结中一点点地学习着概念和算法。图论概念不懂便去查概念,概念差不多了之后便找了份通俗点的代码开始看,光有代码看不懂便又找了好几份解题报告综合起来一起看,后来发现要用tarjan算法,便又去查阅相关tarjan算法的资料,后来始终想不通点双连通分量求法中的dfs函数的运行原理,便又把别人代码这一块切下来,自己改参数、输出结果、画图 阅读全文
posted @ 2011-08-09 19:54 Staginner 阅读(932) 评论(0) 推荐(0)
POJ 3308 Paratroopers
摘要:POJ_3308这个题目有点像二分图最小点集覆盖问题,但由于边带权,所以不能直接用二分图最大匹配来做。参考了别人的想法之后,发现构图的时候原来还是要用的二分图的思想,将行、列分别看做一个集合,由于最后求费用乘积的最小值,所以先传化成log2形式的费用,源点与行之间的容量初始化为log2行费用,列与汇点之间的容量初始化log2列费用。之后对读入的伞兵位置对应的行和列之间连一条有向边,容量为INF。 最后只要求一下最小割就可以了,也就是最大网络流。#include<stdio.h>#include<string.h>#include<math.h>double 阅读全文
posted @ 2011-08-07 14:31 Staginner 阅读(384) 评论(0) 推荐(0)