POJ刷题

题记:刷题有快感不是吗?

这篇文章会持续更新, 记录我所有AC的POJ题目。
PS:我所有的POJ代码都存在我的github上。

1000 A+B Problem

水题不说了。

1001 Exponentiation

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

1002 487-3279

题目描述:

设计程序,按照功能机上的9键键位把字母电话号码转化成数字电话号码,并将电话号码格式化(原本的电话号码格式里可能出现无数个短横线-(=_=#))
对于给定输入,输出有重复的电话号码,并给出重复的次数。

输入格式:

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

输出格式:

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

数据约定:

\( n \leq 100,000 \)

我的做法:

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

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

但是。。就是没有字典树的。。然后我就写个字典树把。。
因为我看到这道题的第一想法是字典树。
但是我WA了5次。。最后发现是个低级错误导致了我的WA、天坑!
因为很久没写代码了,手有点生。
写插入函数的时候。。一开始是写成了这样的。。

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

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

1003 Hangover

题目描述:

原题目的意思太复杂了,不想写了,直接说核心思想:求满足\( \frac{1}{2} + \frac{1}{3} + \cdots + \frac{1}{n} \geq S_{n} \)的最小的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 \geq \pi (x^2+y^2)\)的ans。。。

1006 Biorhythms

题目描述:

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

\[ q+k_1*t_q==e+k_2*t_e==i+k_3*t_i\]

输入格式:

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

输出格式:

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

数据约定:

\(q,e,i,d \leq 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对这道题目来说是一个很好的辅助工具。
看一组数据吧

1
2
3
4
5
6
7
8
9
10
11
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
  • totlen%answer==0 也即answer一定是totlen的约数

其次给长度从大到小排序,这样可以避免无意义的搜索
同一长度的木棒具有同样的效果,即如果第一根该长度的木棒无法满足要求,则跳过所有该长度的木棒(因为结果都一样)
作为当前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了。

1013 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 \leq 200,0 < m \leq 20,0 \leq p,q \leq 20。 \)

解题思路:

DP!!!

状态:\( f _ {i,j} \)表示已经选出来了i个人并且差值为j时的最大和值。
转移:\( f _ {i+1,j+p_{k} - d _ {k}} = max( f_{i,j} + p_{k}+d_{k}) , k \in \left( 1,2,\cdots, n \right) \)
第一重循环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是它本身。
  • 如果一个数的inventory是它本身,则说它是self-inventory的。

如果一个数的第n个inventory是self-inventorying的,则说它在第n步之后是self-inventorying的。

如果一个数进入了一个长度为k的inventory循环,则说它enters an inventory loop of length k。

如果一个数的前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)\)的箱子。
现给出每种物品的数量,求最少要用多少个箱子才能装下所有的物品。

输入格式:

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

输出格式:

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

解题思路:

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

  • 首先:6*6、5*5、4*4的肯定每个物品要占用一个箱子。
  • 其次:每四个3*3的物品要占用1个箱子。
  • 然后:根据上面的数量算出此时要用的箱子数和这些箱子放下上面的四种物品之后还剩下的空间里能放下的2*2的物品数量,然后判断能放下的2*2物品的数量和需要放的2*2的数量的关系,如果放不下,增加箱子数量。
  • 最后:由于此时所有箱子的所有空间一定可以放下22到66的所有物品,所以计算放完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 \leq n,m \leq 100 \)

解题思路:

贪心+枚举

将所有设备以价格为关键字从小到大排序。
然后依次枚举每个设备i,把当前设备i 的带宽当做系统的最小带宽,计算B/P,取所有B/P中的最大值。。这里可以加上一些优化。。
妈蛋的WA了7次。。因为快排写萎了。。。郁闷到死!!!
更详细的看代码注释。PS:第一次写代码注释。。。

1019 Number Sequence

题目描述:

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

输入格式:

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

输出格式:

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

数据约定:

\( 1\leq t\leq 10,1\leq i\leq 2147483647 \)

解题思路:

预处理两个数组,a和b,a[i],b[i]分别表示Si的长度和S1S2·······Si的长度。也就是说b是a的前缀和。这样可以直接算出每个i落在哪一个Sk里面。然后到Sk里面去找第i个位置的数字。。
PS:这绝对不是一道水题!!!!!!我一开始以为是一道水题。。然后坑了3次。。因为他要求输出的是digit是数字!!不是整数,天坑!!

1020 Anniversary Cake

题目描述:

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

输入格式:

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

输出格式:

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

数据约定:

\(1 \leq n \leq 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个四维的小立方体(四维的还能叫立方体?)组成的产品(名字叫做EE3),小立方体之间互相用胶水粘在一起.
现在需要一个程序判断EE3是否合格,如果合格计算EE3的体积(四维情况下还能叫体积么?@O_O@!!)。
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的。
例如:

  • 给定序列长度为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除以二再加一就相当于把这个值修正了。

具体的看代码(这次代码写的好丑T^T):
PS:由于看ICPC的WorldFinal去了,没有第一时间写题解@O_O@!!!
继续看live去惹@O_O@~~~

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:传参数什么的好麻烦,看来下次要写结构体,然后把数据全部封装起来了,那样直接传结构体的地址就好了。

1067 取石子游戏

题目描述是中文的。

解题思路:

威佐夫博弈的三条性质:戳威佐夫博弈-百度百科
威佐夫博弈的公式:\(a _ {k} = [ \frac {\sqrt {5}+1} {2} * k ] \)
通过这个公式(我还没看证明的), 我们可以利用奇异奇异局势的性质b[k]=a[k]+k;来判断题目给出的(a,b)是否是奇异局势。
令\({k}=|a-b| , a_ {k} = [ \frac {\sqrt{5}+1} {2} * k ] \); 判断我们算出的ak是否与题目给出的a相等即可。

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\leq t \leq 10,1 \leq n \leq 20 \)

解题思路:

赤果果的暴力有木有,代码能力强点的一次性都能过。

1088 滑雪

题目是中文的。

解题思路:

记忆化搜索
用逆向思维,从低的点取值取到高的点。这样就不会漏掉状态了。
用f[i][j]表示点(i,j)出发到可以到达的最高的点的距离。
所以搜索点(i,j)的时候,先搜索它周围的四个点,用它周围的四个点的f值更新(i,j)的f值。
也就是说如果\(h(i,j) < h(i \pm 1,j \pm 1)\)
那么\(f(i,j)=max \left( f(i,j), f(i \pm 1,j \pm 1)+1 \right)\)

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”。

解题思路:

没有思路,这就是一道水题。

2001 Shortest Prefixes

题目描述:

顾名思义,找最短的前缀:给定若干个由小写字母组成的串,找出他们的最短的唯一前缀。

输入格式:

输入由若干个只由小写字母组成字符串组成。每行一个字符串。

输出格式:

对于每个串,输出它本身,再输出它和另外任意一个串的最短前缀。

解题思路:

直接上字典树。
每次读入一个字符串,插入到字典树里面,每个节点记录被访问的次数。
插入完毕之后,根据每一个字符串遍历字典树,碰到访问次数为一的节点返回。
输出的前缀即为从串的开头到返回的位置的内容。

数据约定:

输入的串的数量最少两个,最多1000个, 每个串最长20.

2299 Ultra-QuickSort

题目描述:

给一个长度为n的数字序列。求该序列的逆序对数量。

关于逆序对的定义,戳维基百科

输入格式:

输入有多组数据。
每组数据以一个整数n开始,接下来是n行每行一个整数。
第i个整数表示该序列的第i个值\(a_ {i} \)。
输入以n=0结束。

输出格式:

每组数据输出一个值,为逆序对的数量。

数据约定:

\( n\leq 500000, 0 \leq a _ {i} \leq 999999999 \)

解题思路:

离散化+树状数组。————PS:其实还有别的办法的。

为什么要离散化?
因为要以 \( a _ {i} \) 为下标构建树状数组,而 \( a _ {i} \) 的最大值太大。

离散化的方法:
给每个数字按输入顺序打上id,则id的范围为n的范围,然后将序列按值排序,再使用id代替原本的输入顺序构建树状数组。

使用树状数组:
输入一个数 \( a _ {i} \)则用树状数组统计一下 \( 1,a _ {i}) \)区间里面的数字的个数,然后再把 \( a _ {i}) \) 添加进树状数组。
PS:这里是最原始的思想,因为 \( a _ {i} \) 太大,所以需要离散化。然后用id代替 \( a _ {i} \)

2481 Cows

题目描述:

有n头牛,每头牛有两个参数——S和E,现在规定:一头牛(i)比另一头牛(j)的强壮的需要满足:

  1. \(S_{i}\leq S_{j}\)
  2. \(E_{i}\geq E_{j}\)
  3. \(E_{i}-S_{i}>E_{j}-S_{j}\)

现在问,对于每一头牛,有多少头牛比这头牛强壮。。

输入格式:

输入有多组数据。
每组数据以一个n开头,表示有n头牛。
接下来n行,每行两个数,表示一头牛的S和E。
所有输入以0结束。

输出格式:

每组数据输出一行。
每行按照输入的顺序输出每头牛的比他强壮的牛的数量,用空格隔开。

解题思路:

树状数组!!!
话说这道题目让我想起了平衡树试题里面的star那道题目。好像star也可以用树状数组做诶。。
看来线段树,树状数组,平衡树在某些地方是有重合的地方的。

先把所有的牛按照E降序排序。然后统计它的S值之前有多少头牛。然后把它的S加入树状数组。

算法Bug:

两头牛的S和E都相等的情况下。。很坑爹啊。

不过最后我还是在discuss找到了解决办法。

最后还是WA了两次。

PS:还有这是我第一次在算法题里面用自己写的C++对象。

3630 Phone List

题目描述:

给若干个数字串,判断是否有一个串是另一个串的前缀。

输入格式:

第一行是一个整数t,表示有t组数据。
每组数据第一行一个整数n,表示有n个串。
接下来n行,每行一个只由数字组成的串。

输出格式:

判断是否存在一个串是另一个串的前缀。
如果存在,输出”NO”,否则输出”YES”.(不包括引号).

解题思路:

把所有串插入字典树,然后对于每一个串,在它的字典树路径上,找有没有别的串的标记。如果在任意一个串的路径上出现别的串的标记,则输出’NO’,否则输出’YES’。

竟然WA了两次,真的是血崩!!