POJ刷题

这篇文章会持续更新, 记录我所有AC的POJ题目。

PS:我所有的POJ代码都存在我的github上。


1000 A+B

水题不说。

1001 Exponentiation

求一个数的n次方,用高精度,注意细节。

1002 487-3279

题目描述:设计程序,按照功能机上的9键键位把字母电话号码转化成数字电话号码,并将电话号码格式化(原本的电话号码格式里可能出现无数个短横线-(=_=#))

对于给定输入,输出有重复的电话号码,并给出重复的次数。

输入格式:第一行一整数n,表示电话号码的数量,接下来n行字符串,每行表示一个电话号码。

输出格式:若干行,每行一个字符串和一个数字,用空格隔开,字符串表示电话号码(格式化了的),数字表示该电话号码重复了的次数。

数据约定:n<=100,000

我的做法:

看了很多人的解题报告。。发现很多写法:

  • 快排
  • 堆排
  • hash
  • 优先队列

但是。。就是没有字典树的。。然后我就写个字典树把。。因为我看到这道题的第一想法是字典树。。

但是我WA了5次。。最后发现是个低级错误导致了我的WA、天坑! 因为很久没写代码了,手有点生。
写插入函数的时候。。一开始是写成了这样的。。

1 for(; *pst++; ) {
2         int ch = *pst - ‘0‘;
3         if( ptr->child[ch] == NULL )
4             ptr->child[ch] =  ++pbuf;
5         ptr = ptr->child[ch];
6 }

不得不说这是天坑,调试了蛮久的。

1003 Hangover

题目描述:原题目的意思太复杂了,不想写了,直接说核心思想:求满足1/2+1/3+······+1/n>=S的最小的n。

输入格式:多组数据,每组数据一行,每行一个实数,精确到小数点后两位,以0.00结束输入

输出格式:每组数据输出n card(s),0.00不输出

数据约定:这种题目越不约定数据范围有用么?

1004 Financial Management

我不会告诉你这道题目是要求12个实数的平均数的。

1005 I Think I Need a Houseboat

题目描述:有一个半圆从原点每年以一定的速度扩张(往y轴正方向扩张),然后定一些点,要求输出半圆扩张到这些点的时间(年)。。。

输入格式:第一行一个整数n,表示表示点的个数,接下来n行,每行两个实数,x和y,表示这n个点的坐标

输出格式:每个点输出一句话“Property N: This property will begin eroding in year Z.” N表示点的编号(从1开始),Z表示所有的时间(年)。输出文件最后输出一句话:END OF OUTPUT.

数据约定:越不约定数据都没有意义吧?

具体做法:计算最小的满足 ans*100>=∏(x^2+y^2)的ans。。。

1006 Biorhythms

题目描述:已知三个周期tq=23、te=28,ti=33!然后,一个case给你四个数,前三个q、e、i,对应已知的三个周期,是周期开始的时间,然后每个时间你需要输出从第四个数所代表的时间到三个时间经过若干个周期后相等的时间。每个时间的周期数不要求相等,例如q经过了k1个周期,e经过了k2个周期,i经过了k3个周期使得q+k1*tq==e+k2*te==i+k3*ti.

输入格式:多组数据,每组数据四个整数,q,e,i,d,表示的意义在题目描述中说了。以四个-1结束输入。

输出格式:Case M: the next triple peak occurs in N days. M表示数据的组数,N表示满足每组数据的最小的天数。

数据约定:q,e,i,d<=365。

我的思路:

这是一道坑爹的数学题!以前根本没学过的中国剩余定理。因为我想了蛮久还没有头绪,自己本身解数学题的能力就不行,然后就进discuss看了看别人的想法,然后发现有人给出了他的算法:

  • 把三个时间看做三个跑步的人,他们的初始位置由输入给定
  • 他们的步距是已知的周期,然后第四个给定的时间是初始的目的地
  • 然后进入循环
  • 1:让他们每个人按周期先跑到大于等于目的地的位置
  • 2:判断他们的位置是否相等,相等则输出answer,结束循环,否则转3
  • 3:取他们三个的位置的最远处为新的目的地,转1

简直佩服想出这个算法的人。。简洁明了的AC了。 
用了这个算法,讨论区里好多人说的什么注意边界条件,注意特殊情况的问题都不存在了。。简直好。真心Orz想出这个算法的人。

但是后来发现其实这个题目直接用定理一步到位。还是要好好学习一下中国剩余定理的说。

1007 DNA Sorting

题目描述:定义一个串的混乱度为:每个字符右边的比该字符小的字符数量的总和。例如用P(i)表示第i个字符右边的比它小的字符的数量,那么一个串的混乱度就是∑P(i)。

现在要求设计程序,对输入的DNA串按照混乱度从小到大的顺序排序,然后输出。

输入格式:第一行一个整数n,表示输入的DNA串的数量,接下来N行每行一个字符串,只由ATCG四个字母组成。

输出格式:n行,每行一个串,按混乱度从小到大排序。

我的做法: 直接用三重循环(不会超时)实现读取加处理,然后选择排序,然后输出就过了。 简直炒鸡水0.0

1008 Maya Calendar

这道题目POJ有中文翻译,就不叙述题目意思了。

其实也是炒鸡水题,注意细节,细节,细节,重要的事情说三次。

1009 Edge Detection

题目描述:IONU Satellite Imaging, Inc公司运用一种叫做run length encoding的技术记录和存储图片,每一个像素点用一个数字表示。现在要求设计程序,对于给定的图片,进行算法压缩,把每个像素点编码成另一种格式,每一个像素点的值分别与它周围的八个点的值相减,取最大的绝对值为这个点新的像素值。

输入格式:输入有多组数据,每组数据第一行一个整数w,表示图片的宽度。接下来若干行,每行两个整数,分别表示该像素的连续个数和该像素的值。以 0 0结束一组数据的输入,以单行一个0结束输入。

输出格式:每个数组输出若干行,跟输入相似的有,第一行一个整数w,表示宽度,接下来若干行,每行两个整数,分别表示像素连续的个数和值。同样以0 0表示一组数据输出的结束,以单行一个0结束输出。

我的思路:好吧,我一看到这道题目是没有思路的,除了暴力。当然,暴力肯定会TLE的,故看了别人的想法。感谢这个博客给了我很大的启发。

根据题目给出的条件——pair最多只有1000对,然后仔细思考会发现,如果只对像素发生变化的地方进行计算——也就是题目里说的编码了。
这个的证明我找了好久没找到,一些博客里给出的证明链接已经失效了。
但是这样是可行的,我也不知道为什么可行,找不到证明。。不过即使是知道了算法,我还是在写代码的过程中出现了问题。某个地方少写了一个等于号,然后WA了两次。其实是这样的——我们需要对最后一个点进行编码。。因为,。。因为我也不知道为什么(不过这里似乎给粗了解释)。
然后我把某组数据用excel画粗来了。。嗯,excel对这道题目来说是一个很好的辅助工具。
看一组数据吧
30
0 10
10 62
5 20
15 62
5 20
25 6
5 15
0 9
25 6
0 0
用excel画出来是这样的

其中需要编码的点我用金黄色的标记了粗来,确定编码位置的点橘黄色的标记了,编码完之后是这样的

这里要尤其注意,最后的最后,一定要在最后进行一次编码,也就是其实已经超出长度的那个地方。。但是就是一定要在那个excel表第8行和第15行的那里编码一次。。不然就会有bug。体现到代码里面就是 进行跳跃的标记变量p要做到等于pairnum的地方。。实际上有数字的地方只是0~pairnum-1。。for(p = 0; p <= pairnum; ++p)。。我就是少写了那个等号。。然后WA两次。

1010 STAMPS

 题目描述:现有若干种邮票,每种邮票有一个面值(不同种邮票的面值可以相同),要求设计程序,对于每一个用户要求的总面值给出相应的最优的邮票方案。

对最优的定义如下:

  • 首先,邮票的数量要尽量多。但是以为顾客只能给4张邮票。
  • 其次,如果存在两个以上的最优解的邮票种类是一样的,张数最少的更优
  • 再其次,张数也一样的话,这些最优解中最大面值较大的更优。
  • 最后,若邮票种类、张数、最大面值三者都分别相同,则认为这些最优解相同。

输入格式:输入有多组数据,每组数据由两行组成。

  • 第一行若干个数字,表示邮票的面值,每一个数字就是一个不同的种类,哪怕面值相同。以0结束。
  • 第二行若干个数字,表示顾客所需要的邮票总面值。每个数字就是一个顾客的需求,以0结束。

以EOF结束输入。

输出格式:每个顾客的需求输出一行,

如果这个顾客的需求没有解,输出"n ---- none",其中n是顾客要求的面值。

否则输出可行解,"n (x): x1 x2 x3 x4",其中n是顾客要求的面值,x是可行解的邮票的种类数,x1-x4表示每种邮票的面值,从小到大输出,没有的不输出。例如只有两种则只输出"n (2): x1 x2"。

数据约定:每个顾客最多拿四张邮票似乎就是约束条件。

我的思路:这是一道该死的搜索题。

由于搜索方面的薄弱,so借鉴了这个博客的思考。

我采用的是dfs的搜索方法。从上面那个博客里学到的优化。还有使用std函数sort排序。哈哈哈好方便的说。

不知道为什么,我总是想不到搜索的剪枝,例如这道题里面的对邮票的面值进行排序。。超过5张面值一样的邮票,直接算5张,我觉得我真的很难想的到。。我直接看别人的剪枝方法,是因为我实在对自己的搜索没有信心。。。搜索TLE太多次。。好伤!

感觉搜索的优化就是一件拼智商的事。

1011 Sticks

题意就不说了,有中文。 
思路是:搜索+高难度剪枝。 
其实这道题在POJ上的数据太渣。水水的剪枝就可以过。但是UVA的那道一样的题目不行。。推荐一个好的题解。 
这道题目一开始我只想到3个剪枝方法。然后百度到了另外3个。

  • 首先确定答案的范围,答案必然满足maxlen<=answer<=totlen/2 或者 answer==totlen
  • 然后answer一定是totlen的约数即必须有 totlen%answer==0
  • 其次给长度从大到小排序,这样可以避免无意义的搜索
  • 同一长度的木棒具有同样的效果,即如果第一根该长度的木棒无法满足要求,则跳过所有该长度的木棒(因为结果都一样)
  • 作为当前possibleanswer的开头第一个木棒必然是当前可用木棒集合中最长的,如果最长的都无法满足要求,则当前possibleanswer一定impossible。如果当前碎木棒正好使得正在拼的木棒满足当前的possibleanswer,但是在它之后的其他木棒无法完成该possibleanswer,则正在拼的这根木棒一定无法满足该possibleanswer。

1012 Joseph

题目描述:经典的约瑟夫环问题。有n个人围成一个环,给定一个m,从0开始报数,报到第m个数的人出局,然后从此人后一个人继续从0开始报数,直到全部人都出局。现在问:对于给定的k,表示有2k个人,然后要求输出一个m使得第一次有前k个人里的人出局时,后k个人已经全部出局。 
输入格式:若干行,每行表示一个输入——k,以0结束 
输出格式:每个k输出一行,表示满足条件的m 
数据保证:0< k <14 
解题思路:一开始我是想直接打表的。毕竟k最大才13。。然后想了想还是写一个有点意义的程序吧。。然后模拟了一下报数。。然后就AC了。

POJ Counterfeit Dollar

题目描述:12个金币中有一个是假币,假币的大小颜色都和真的一样,只有重量不一样,但是有可能比真的轻,也有可能重,现在要通过称重找出那个假的。
输入格式:第一行一个整数n,表示有n组数据,每组数组有3行输入,每行由被2个空格隔开的三个字符串组成,表示一次称重的结果,前字符串由A-L的大写英文字母组成,分别表示天平左边和右边分别放的金币编号。第三个字符串有三种情况”even”,”up”,”down”.分别表示平衡,左边轻,右边轻。
输出格式:每组数据输出一行,表示哪个金币是假币,并输出是比真币重还是轻。例如:K is the counterfeit coin and it is light.
数据保证:并没有任何保证,如果只有12个币不算的话、

解题思路:

  • 首先明确的是,如果是even,则此次称重的所有金币(左右两边的)都是真的。
  • 其次,又在重的一边出现过又在轻的一边出现过的金币是真的。(即在两次称重中处于不同的状态的金币是真的)
  • 最后,在重的一边或轻的一边次数最多的是假币(这个我也不知道为什么,我按照前面两点写出来的算法有错误,然后对着数据看了一下,假币up的次数多,所以。。。)

PS:最近两道题目的题意都是我自己看懂的。没看翻译,只是想好好练习我的英语,似乎效果还可以,要坚持下去!

1014 Dividing

题目描述:有一堆石头,每块石头都有一个value,value只有六个数字0-6,现给出每个value的石头的个数,问,这堆是有能否分成value和相等的里两堆。

输入格式:每行一组数据,每行六个整数n1,···,n6,分别表示value为i(i=1···6)的石头的个数。以0 0 0 0 0 0结束输入(该组数据不输出结果)

输出格式:每组数据都要输出一行”Collection #k:”,k是数据的编号,然后输出一行”Can be divided.”或者”Can’t be divided.” 然后每组数据都要输出一个空行!

数据约定:每种value的石头的个数不超过20000.

我的解题过程:

这道题目我还是想了蛮久的,发现只有搜索可行。然后,我可耻的TLE了,当然,我并没有submit。。我用的discuss里面的童鞋提供的一组十分强大的数据。。然后我可耻的不知道怎么剪枝了,然后可耻的看了讨论,看了别人的剪枝,此剪枝号称最强的剪枝,但是似乎并不是。。因为用上面的数据测试之后还是可耻的TLE了。。然后在这个讨论的子讨论里我发现了一个更神奇的剪枝,然后我神奇的AC了。。。

我的分析:对于一种value的石头,如果它的数量达到了能够用一定数量的一种石头让价值和达到60,那么完全可以忽略这些个石头。

思考:为什么是60这个数字? 因为。。。1~6的最小公倍数是60.因此,如果value为1的石头,那么它的数量里超出60的部分就完全可以不用考虑。。因此 num[value1] %= 60; 因此。。这个剪枝。。墙大了。num[value(i)] %=(60/i);这样。。数量一下子就减小了。。搜索完全无压力。

1015 Jury Compromise

题目描述:有n个人,需要从中选出m个人,每个人都有一个d和一个p值,要求选出来的m个人满足:在所有的方案中,所有人的p值之和减去所有人的d值之和的绝对值最小,如果最小的绝对值相等,则取p值之和加上d值之和最大的方案。 
输入格式:有多组数据,每组数据n+1行,第一行两个整数n和m,接下来n行每行两个整数,表示每个人的d值和p值,以0 0结束输入。 
输出格式:每组数据输出三行,第一行表示当前数据组数的字符串(“Jury #1”,”Jury #2”, etc.),第二行输出表示该方案的所有人的d值之和与p值之和的字符串(“Best jury has value P for prosecution and value D for defence:”),第三行输出该方案选出来的人的编号,每个人的编号之前都有一个空格。每组数据输出完之后输出一行空格。 
数据约定:0 < n <= 200,0< m <= 20,0 <= p,q <= 20。 
解题思路:DP!!!

  • 状态:f[i][j]表示已经选出来了i个人并且差值为j时的最大和值。
  • 转移:f[i+1][j+p[k]-d[k]] = max{f[i][j]+p[k]+d[k]},第一重循环i从1开始枚举,第二重循环j从-400枚举到+400(具体实现需要把j整体移400,C数组下标从0开始的),第三重循环k从1枚举到n。。。

一开始我以为是搜索。。妈蛋的谁叫前面的两道题都是搜索。。后来发现是DP,然后想了想状态和转移,发现还要记录路径,天坑。。。然后我就可耻的看了别人的题解。发现其实dp的时候带上路径并没有想象中的那么难。。但是不知道为什么讨论区好多人说标准的dp解法有错误。。不懂。。。。

1016 Numbers That Count

题目描述:

  • 定义一个整数的inventory为:从0到9排列的(数字的个数+数字)。 例如”5553141”里面有2个1、1个3、1个4、3个5。所以”21131435”是”5553141”的inventory。
  • 定义一个整数的第n(n>1)个inventory为:它的第n-1个inventory的inventory。
  • 定义一个整数进入一个长度为n的inventory循环为:它的第n个inventory是它本身。
  1. 如果一个数的inventory是它本身,则说它是self-inventory的。
  2. 如果一个数的第n个inventory是self-inventorying的,则说它在第n步之后是self-inventorying的。
  3. 如果一个数进入了一个长度为k的inventory循环,则说它enters an inventory loop of length k。
  4. 如果一个数的前15个inventory都不满足上述三个条件的话,则说它can not be classified after 15 iterations

输入格式:有多组数据,每组数据输入一行,每行一个整数n,n为-1时结束输入 
输出格式:每组数据都输出下面四句话中的一句:

  • n is self-inventorying
  • n is self-inventorying after j steps
  • n enters an inventory loop of length k
  • n can not be classified after 15 iterations

数据约定:n最大不超过80位。 
解题思路:我约定不会告诉你这是一道水题的。题解藏在数据规模里。

1017 Packets

题目描述:有六种size(1*1,2*2,3*3,4*4,5*5,6*6,)的物品,只有一种size(6*6)的箱子。现给出每种物品的数量,求最少要用多少个箱子才能装下所有的物品。

输入格式:有多组数据,每组数据一行,每行六个整数,分别表示从1*1到6*6size的物品的数量。输入以6个零结束。

输出格式:每组数据输出一行,每行一个整数,表示最少的箱子数量。最后六个零不输出。

解题思路:特么的就一道贪心水题。。结果我特么WA了四次。。不得不说是天坑。感觉自己好渣渣。在讨论区看到一个漂亮的算法。

  1. 首先:6*6、5*5、4*4的肯定每个物品要占用一个箱子。
  2. 其次:每四个3*3的物品要占用1个箱子。
  3. 然后:根据上面的数量算出此时要用的箱子数和这些箱子放下上面的四种物品之后还剩下的空间里能放下的2*2的物品数量,然后判断能放下的2*2物品的数量和需要放的2*2的数量的关系,如果放不下,增加箱子数量。
  4. 最后:由于此时所有箱子的所有空间一定可以放下2*2到6*6的所有物品,所以计算放完2*2到6*6的所有物品之后箱子还剩下的1*1空间数量,与1*1物品的数量比较,如果不能放得下,增加箱子的数量。

1018 Communication System

题目描述:有一批订单(order),需要n种设备组成一个交流系统。每种设备有m个设备制造商,每个设备制造商的设备都有不同的带宽(bandwidth)和价格(price)。 
定义系统的带宽(B)为这个n个设备里面的最小带宽 
定义系统的价格(P)为n个设备的总价格 
现在要求你设计程序计算从设备制造商提供的所有设备中选出n个(每种一个)使得系统的B/P最大 
输入格式:第一行一个整数t,表示总共有t组数据。以下每组数据第一行一个整数n,表示设备的种类,以下n行每行开头一个整数m(i)表示第i种类的设备制造商的数量。 m(i)后面接着m(i)对整数,每对整数表示这m(i)个设备的带宽和价格。 
输出格式:每组数据输出一行一个小数,表示最大的B/P 
数据约定:1<=n,m<=100 
解题思路:贪心枚举 
  将所有设备以价格为关键字从小到大排序。然后依次枚举每个设备i,把当前设备i 的带宽当做系统的最小带宽,计算B/P,取所有B/P中的最大值。。这里可以加上一些优化。。 
妈蛋的WA了7次。。因为快排写萎了。。。郁闷到死!!! 
更详细的看代码注释(github)。PS:第一次写代码注释。。。

1019 Number Sequence

题目描述:有一个数列S1S2·····Sk,Sk是由从1到k的数字组成的数列,例如这个数列的前80个数字是: 11212312341234512345612345671234567812345678912345678910123456789101112345678910 现在给定一个数字i,要求给出该数列的第i个位置上的数字!!

输入格式:第一行一个整数t,表示有t组数据,接下来是t行,每行一个整数i,表示要求的位置i。

输出格式:每组数据输出一行,每行一个数字!

数据约定:1<=t<=10,1<=i<=2147483647

PS:这绝对不是一道水题!!!!!!我一开始以为是一道水题。。然后坑了3次。。因为他要求输出的是digit是数字!!不是整数,天坑!!

解题思路:预处理两个数组,a和b,a[i],b[i]分别表示Si的长度和S1S2·······Si的长度。也就是说b是a的前缀和。这样可以直接算出每个i落在哪一个Sk里面。然后到Sk里面去找第i个位置的数字。。

1020 Anniversary Cake

题目描述:有一个边长为size的正方形蛋糕,现在问这块蛋糕是否恰好能被分成n块特定边长的正方形小蛋糕。

输入格式:第一行一个整数s,表示有s组数据,每组数据一行,每行开头一个整数s,表示大蛋糕的边长,然后是一个整数n,表示小蛋糕的数量,接下来n个整数,代表这个n块小蛋糕的边长。

输出格式:每组数据输出一行,”KHOOOOB!”或者”HUTUTU!”,分别代表恰好可以分和不能分。

数据约定:1<=n<=16, 小蛋糕的边长不大于10

解题思路:搜索!!反过来想,把分割大正方形看成往大正方形里放小正方形。

抓住核心思想:只要任何一个小正方形无法被放进去,则该组数据一定无解!所以,可以贪心!

1021 2D-Nim

题目描述:判断两个图是否等价。

对等价的定义是:两个图有相同个数的连通块,第一个图里面的每个连通块总能在第二个图里面找到一个连通块(未与别的块匹配)与之匹配。

对连通块匹配的定义是:两个连通块如果能经过若干次平移、对称、旋转等操作之后重合,则说它们是匹配的。

现在要求设计程序,输入两个图,输出它们是否等价。

输入格式:第一行一个整数t,表示有t组数据,接下来t组数据,每组数据由3行构成,第一行三个整数w,h,n,分别表示图的宽度,高度,和点的数量。接下来两行,表示两个图的点,每行n对整数,分别表示n个点的x和y。

输出格式:每组数据输出一个YES或者NO。

解题思路:找出两个图的所有连通块,对每个连通块进行hash,hash值是连通块里面所有点两两之间距离的平方和。然后将连通块按hash值排序。判断是否有不匹配的连通块。 
更具体的在代码里面。

1022 Packing Unit 4D Cubes

题目描述:有一个由n个四维的小立方体(四维的还能叫立方体?* v *)组成的产品(名字叫做EE3),小立方体之间互相用胶水粘在一起,现在需要一个程序判断EE3是否合格,如果合格计算EE3的体积(四维情况下还能叫体积么?@[email protected]!!)。

EE3合格的条件:所有的小立方体都连通,并且任意两个相邻的小立方体只公用一个维度,且在该维度上互相在对方的相反方向上。

提醒:每一个小立方体都有8个面(因为四根坐标轴0.0)。

输入格式:第一行一个整数t,表示输入有t组数据。

接下来t组数据,每组数据第一行一个整数n,表示该组数据有n个小立方体。

接下来是n行,每行9个数字,第一个数字是第n个小立方体的identifier,后面八个数字是与该小立方体相连的小立方体的identifier(!!!注意是identifier)。每两个数字是一条坐标轴的两个方向。

输出格式:每组数据输出一行,一个整数或者”Inconsistent”,如果输入的n个小立方体无法组成一个合格的EE3就输出”Inconsistent”,否则输出一个整数,表示该EE3的体积。

解题思路:从第一个输入的小立方体开始,bfs每一个与它连通的小立方体,如果有的小立方体没有被遍历到,说明Inconsistent,如果某两个小立方体不符合在他们共同的维度上方向相反的条件。

1023 The Fun Number System

题目描述:给一个长度为k的二进制符号序列,每一位都有两种状态,正的(用p表示)和负的(用n表示),给一个n,现在要求有没有满足条件的二进制数在按照给定的序列转化成10进制后等于n的。 
example:例如给定序列长度为4,二进制符号序列是ppnn,给定n为10,则二进制数为1110,因为1*2^3+1*2^2-1*2^1-0*2^0==10。 
输入格式:第一行一个整数t,表示有t组数据,每组数据三行,第一行是一个整数k,表示二进制符号序列的长度,第二行是一个长度为k的字符串,由p或者n组成,第三行是一个整数n。 
输出格式: Impossible或者一个二进制数,如果符合条件的k位二进制数没有,则输出Impossible,否则输出满足条件的二进制数。 
解题思路: 这道题我一开始看了之后完全没有头绪。。。。然后我随便试了试自己的一个想法,也不知道对不对。我的想法:

  • 首先可以肯定的是,如果n是偶数,那么它的最低位一定是0,不管它的最低位是n还是p;如果n是奇数,那么最低位是1,那么,问题来了,问题是什么呢?等下看第三条。
  • 现在可以肯定的是如果n是偶数,那么它的最低位一定是0,那么我们就可以考虑n/2的情况了,是不是把n右移一位。试想,如果,每次把n右移一位,是不是都可以确定二进制数的一个binary位。
  • 那么现在来考虑如果n是奇数的情况。好吧,我也不知道为什么,我就是鬼使神差的这样处理了:如果n是奇数那么我就把n右移一位然后加一。

当时并没有想这是为什么,然后答案竟然对了。。然后是处理一些小细节,例如n是9223372036854775807的时候,必须先把n右移再加一。。还有就是n的范围需要是long long。。。
然后现在想想,发现好像就是,如果n是奇数时k-1位是正的,那么没问题,这个位一定是1,也不需要改n,如果这个位是负的,那么跟正的相比,差了两个当前k-1位大小的值(2^k),然后我们把n除以二再加一就相当于把这个值修正了。
具体的看代码(这次代码写的好丑TnT): 
PS:由于看ICPC的WorldFinal去了,没有第一时间写题解@[email protected]!!! 
继续看live去惹@[email protected]~~~

1024 Tester Program

题目描述:给定走出一个迷宫的最短路径,再给出一个由这个最短路径算出来的解(一个墙的结合),现在要有设计程序判断该解是否正确。

正确的标准:最短路径为给出的最短路径且唯一,如果给出的解(墙的集合)组成的迷宫的最短路径比给定的最短路径长或短都不行,一定要一样长且只有给定的那一条路是最短路。

输入格式:多组数据,第一行为一个整数t,表示数据的组数

每组数据包括一个原始问题输入和一个原始问题输出。

原始问题输入就是给定的最短路径,格式如下:

  • 第一行是两个整数w和h,表示迷宫的宽度和高度,
  • 第二行是一行由四个字母(‘U’,’D’,’R’,’L’)组成的字符串,U表示向上走,D表示向下走,R表示向右走,L表示向左走。

原始问题输出就是一个墙的集合,格式如下:

  • 第一行一个整数n,表示有n个墙
  • 接下来是n行,每行四个整数,两个点的坐标,表示这两个点之间有一堵墙。

输出格式:输出CORRECT或者INCORRECT,表示原始问题输出正确或者不正确。

解题思路:一开始只想到了怎么判断最短路径是否唯一,但是不知道怎么判断墙是否多余,然后在discuss里面看到一个绝妙的算法,具体的想法如下:

  • 分别从起点到到终点和从终点到起点进行bfs,通过bfs分别算出从起点到每个点的最短距离dis1和从终点到每个点的最短距离dis2。
  • 把给定的最短路径所经过的点打上标记,再把所有墙两边的点打上标记
  • 然后对所有没有标记的点进行判断,如果存在一个点满足dis1+dis2==pathlen(给定的最短路径的长度),那么则最短路径不唯一
  • 然后判断是否有墙多余,枚举每个墙两边的点(分别记为a和b),如果从起点到a的距离加上从终点到b的距离和从终点到a的距离加上从起点到b的距离都大于pathlen,那么当前的墙是多余的。
  • 注意一个特殊情况!!!!如果出现一个被墙围起来的封闭区域,那么一定会有一个墙多余。但是bfs算不出来,需要进行特判。

下图是特殊情况

具体见代码! PS:传参数什么的好麻烦,看来下次要写结构体,然后把数据全部封装起来了,那样直接传结构体的地址就好了。

1068 Parencodings

题目描述:一个括号序列S可以用两种方式编码:P序列和W序列。 
两种编码方式得到的序列定义如下:

  • P=P1P2······Pn, Pi表示从左至右每一个右括号左边有多少个左括号。
  • W=W1W2······Wn,Wi表示从左至右每一个右括号匹配的左括号是从它

开始往左数的第几个左括号。

例如:

  • S= (((()()())))
  • P= 4 5 6 6 6 6
  • W= 1 1 1 4 5 6

现在要求设计程序,输入括号序列的P序列,输出其对应的W序列。

输入格式: 
第一行一个整数t,表示输入有t组数据。 
每组数据两行。 
第一行一个整数n,表示P序列的长度。 
第二行n个整数,表示P序列。 
输出格式: 一行n个整数,表示对应的W序列。 
数据约定: 1<=t<=10,1<=n<=20 
解题思路: 赤果果的暴力有木有,代码能力强点的一次性都能过。

1611 The Suspects

题目描述:有n个人,m个小组,每个小组里的人会互相传染,要求设计程序统计有多少人是被感染了的。编号为0个人是一定被感染的。

输入格式:多组数据,每组数据第一行是两个整数n和m,表示总共有n个人,m个小组,接下来是m行,每行多干个整数,第一个整数k表示这个小组里面有k个人,接下来k个整数表示这个小组里的人的编号。输入以0 0 结束。

输出格式:每组数据输出一个数字x,表示有x个人是被感染了的。

解题思路:简单并查集,不多说。

1936 All in All

题目描述:设计程序,输入两个串,判断是否能在删除第二个串里面的一些字母后使得它与第一个串相等。

输入格式:多组数据,每组数据一行,每行两个串,用空格隔开,只由大小写英文字母组成(区分大小写)。

输出格式:每组数据输出一个单词 "Yes" or "No"。

妥妥的水题。

时间: 2024-09-30 20:42:13

POJ刷题的相关文章

POJ 刷题指南

OJ上的一些水题(可用来练手和增加自信) (POJ 3299,POJ 2159,POJ 2739,POJ 1083,POJ 2262,POJ 1503,POJ 3006,POJ 2255,POJ 3094) 初期: 一.基本算法: 枚举. (POJ 1753,POJ 2965) 贪心(POJ 1328,POJ 2109,POJ 2586) 递归和分治法. 递推. 构造法.(POJ 3295) 模拟法.(POJ 1068,POJ 2632,POJ 1573,POJ 2993,POJ 2996) 二

算法之路——POJ刷题(Java,持续更新中)

先拿一些水题来练手了 1.POJ1000 import java.util.Scanner; /** * Created by mxcsky on 2015/1/25. */ public class POJ1000 { public static void main(String[] args){ Scanner in = new Scanner(System.in); int a = in.nextInt(); int b = in.nextInt(); System.out.println

POJ刷题(2499)

程序(已经Accepted): #include <stdio.h> /* * 逆向思维,从(m,n)到(1,1), * 给定(m,n),求其父亲,若m>n,则其父亲为(m-n,n),否则为(m,n-m), * 但是这样做会TLE,这就需要用除法代替减法,加快速度, * 也就是辗转相除法 * */ int main(void) { int n, a, b, l, r, temp, i; scanf("%d", &n); for(i=0; i<n; i++

POJ刷题(2013)

程序(已经accepted): #include <stdio.h> int main() { char name[15][26]; int n, i; int N = 1; while(scanf("%d\n", &n) == 1 && n) { for(i=0; i<n; i++) gets(name[i]); printf("SET %d\n", N++); for(i=0; i<n; i+=2) puts(na

POJ刷题(2406)

程序(已经accepted): #include<stdio.h> #include<string.h> #include<memory.h> #define N 1000010 char str[N]; int next[N]; int get_next(char pattern[], int next[]) { int j=0,k=-1; int len=strlen(pattern); next[0]=-1; while(j<len) { if(k==-1|

[转]POJ的刷题指南(加了超链接的)

网上看到的转过来一下,顺便把题目都加了个超链接,方便刷起~ POJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094) 初期: 一.基本算法:       (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.       (4)递推.       (5)构造法.(po

acm刷题记录

我感觉毫无目的地刷题没有意义,便记录每周的刷题,以此激励自己! ----------6.6-------- [vijos1055]奶牛浴场                                      最大化               推荐IOI论文<浅谈用极大化思想解决最大子矩形问题> codeforces 679B - Bear and Tower of Cubes      xjb搞 codeforces  680A - Bear and Five Cards       

7、8月刷题总结

准备开学了囧,7.8月刷题记录,以后好来复习,并且还要好好总结! 数据结构: splay: [BZOJ]1503: [NOI2004]郁闷的出纳员(Splay) [BZOJ]1269: [AHOI2006]文本编辑器editor(Splay) [BZOJ]1507: [NOI2003]Editor(Splay) treap: [BZOJ]1862: [Zjoi2006]GameZ游戏排名系统 & 1056: [HAOI2008]排名系统(treap+非常小心) [BZOJ]3224: Tyvj

比较好的刷题网站推荐

1.Leetcode鼎鼎大名的Leetcode,据不完全统计在上面被刷过的题可以围绕地球三圈.(没说赤道哈,就是这么严谨.)总之,很多国内外的码农在上面刷题.难度从easy到hard都有,而且覆盖面极广.现在还增加了数据库和shell,相匹配的论坛也可以多看看.很锻炼和国外码农沟通的能力,对于以后去混Github也有好处. 特点:各种语言支持很广泛,题型覆盖很广,测试数据集较弱. 2.Codility同样一家著名的国外刷题网站.和Leetcode不同,它是专门帮各大软件公司笔试用的,只是副业提供