摘要: 题意:魔王将在T时刻吃掉公主,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。如果骑士们在T时刻能找到公主就输出“YES”,否则输出“NO”。分析:简单广搜,要注意的是,一旦进入传输机就被传送到另一层,不能在传输机上停留。另外,若另一层的相对位置也是传输机,则不能传输,两个传输机都应视为墙。int dx[] = {-1,0, 阅读全文
posted @ 2013-05-28 20:15 心向往之 阅读(180) 评论(0) 推荐(0) 编辑
摘要: 题意:从 n (1<=n<=200)个候选人中选 m (1<=m<=20)人组成陪审团。控方和辩方给所有候选人打分D[i]和P[i],分值从0 到20。为了公平起见,法官选出陪审团的原则是:选出的m 个人,必须满足辩方总分D和控方总分P的差的绝对值|D-P|最小。如果有多种选择方案的|D-P|值相同,那么选辩控双方总分之和D+P最大的方案。分析:用dp(i,j)表示取i个候选人,差为j的总和。则转移函数为 dp(i, j) = max dp(i-1, j-Vt), (t在i-1个人中没被选到,Vt=Dt-Pt)。此题要记录选了哪些人,用path[i][j]表示dp[i] 阅读全文
posted @ 2013-05-28 18:47 心向往之 阅读(168) 评论(0) 推荐(0) 编辑
摘要: 题意:n个点(n<=1000),m条有向边(m<=20000),起点s,有的点是P类型,有的点是T类型,求最短的到达P型点的路线,要求路径长度能被k整除(k<=1000),输出长度和终点编号。若有多条,输出终点编号最小的。分析:一开始看点很多,又能重复走,觉得深搜爆栈,所以广搜,果断爆空间。。后来深搜,若有两个长度d1,d2模k余数相同,只保留较小的那个。const int N = 1005, M = 20005;int n, m, s, p, ansv;LL k, ansd;int head[N];char c[N];struct nod{ int v, next; LL 阅读全文
posted @ 2013-05-27 22:12 心向往之 阅读(411) 评论(0) 推荐(0) 编辑
摘要: 题意:十二面体有20个顶点,每个顶点和相邻3个顶点相连,问从一个顶点出发,每个顶点只走一遍,回到原点的走法。如果有多条,按字典序输出。分析:将每个顶点的相邻点排序,然后简单深搜。。。int a[21][3];int m, cnt;int p[21], b[21];void d(int i, int u){//第i步为顶点u if(i==19){ FOR(j, 0, 3) if(a[u][j] == m){ printf("%d: ", ++cnt); FOE(k, 0, 20) printf(... 阅读全文
posted @ 2013-05-27 14:40 心向往之 阅读(118) 评论(0) 推荐(0) 编辑
摘要: 题意:地球纬度长L,青蛙A和青蛙B同时向西跳,起点分别为x,y,速度分别为m,n,问多久相遇?分析:( x + mt ) - ( y + nt ) = kL=>( m - n ) t - ( y - x ) = kL=>( m - n ) t - kL = ( y - x )令 a = m - n , b = L , c = y - x , X = t , Y = k则原等式转换为 aX-bY=c, 剩下就是扩展gcd了。。LL gcd(LL x, LL y){ if (!x || !y) return x + y; for (LL t; t = x % y; x = y, y.. 阅读全文
posted @ 2013-05-26 22:42 心向往之 阅读(140) 评论(0) 推荐(0) 编辑
摘要: 题意:一个数列,每次可交换两个数,交换的代价为这两个数的和,要把这些数按升序排列,问最小的代价?分析:对于任意循环i,设长度为ki,则至少交换ki-1次,即每次让一个元素到达正确位置,第ki-1个到达后,第ki个自然也在正确位置。一种方法是让最小元素ti参加所有交换,其它元素各参加一次,总代价为:sum(i)+(ki-2)*ti, sum(i)为循环i所有元素之和。 另一种方法是让ti和n个数中最小的数m交换,然后m和循环里的其它数交换,最后再让m和ti交换,总代价为:sum(i)+ti+(ki+1)*m,最终答案为两种代价的较小者。。const int maxn=10005;struct n 阅读全文
posted @ 2013-05-26 22:30 心向往之 阅读(109) 评论(0) 推荐(0) 编辑
摘要: 题意:问一个置换f,能不能表示成两个置换g的平方?分析:奇置换的平方为一个等长奇置换 偶置换的平方为两个原置换一半长度的置换所以如果有两个相同长度的偶置换,则可以由另一个2倍长度的偶置换平方得到,求出不同长度的偶置换的个数,若都为偶数个,则f可以表示成g*g,否则不可以。int n;char s[27];int b[27],c[14];int main(){ scanf("%d",&n); while(n--){ scanf("%s",s); memset(b,0,sizeof b); memset(c,0,sizeof c); ... 阅读全文
posted @ 2013-05-26 22:19 心向往之 阅读(135) 评论(0) 推荐(0) 编辑
摘要: 题意:6个数字,每次可以左移/右移光标,或将光标所在数字加一/减一,或将光标所在数字与第一个/第六个数字交换,问达到目标数字,最少需要多少次操作?分析:操作可以分成两部分考虑:移动光标和交换改变了原数字的位置,而加一减一改变数字的大小。先bfs出012345所能达到的所有状态,以及达到此状态光标经过了哪些数字。再针对新状态和目标状态,如果某一位数字不一样并且光标经过这一位,则可以改变此数字的大小,若没经过,则此状态无法达到目标状态。表达起来太费劲了,直接看代码吧。另外,据说左移操作是多余的,把代码中左移部分去掉,也AC了,但还是感觉有问题。。 有空再想吧。。const int M = 567; 阅读全文
posted @ 2013-05-26 20:46 心向往之 阅读(402) 评论(0) 推荐(0) 编辑
摘要: 题意:n×m (1<= N, M <=477) 的矩阵,a[i][j]表示第i行第j列的能量值,可以从任意点出发,任意点停止,但只能往右或往下走。第一步给自己补充能量,第二步给剑补充能量,依次循环补充。能量值0~10,若当前为10,又补充了1的能量,则能量变成0。要求离开的时候,人和剑的能量值相同,问有多少种不同的走法?结果对1 000 000 007取余。分析:枚举人和剑的差值,人比剑多s,相当于人比剑少11-s。。。设dp[x][y][i]表示在(x,y)位置,差值为i的方案数,dp[x][y][i] = ( dp[x][y][i] + dp[x+1][y][j] ) 阅读全文
posted @ 2013-05-26 14:12 心向往之 阅读(167) 评论(4) 推荐(0) 编辑
摘要: 题意:有n个数,从中取连续的一段,使其和为n的倍数。 3370求的是部分和为c的倍数(c<=n)。分析:设前k个数的和 S(k)=a1+a2+...+ak,若S(k)为n的倍数,输出前k个数即可。否则 n 个 S(k) 除以 n 的余数只能有1,2,3...n-1,这(n-1)种情况,由鸽笼原理知,必有两个不同的和S(i)和S(j) (i<j)除以n的余数相同 ,故部分和S(j)-S(i) = ai+1+...+aj是n的倍数。poj 2356const int M = 10005;int n, s;int a[M], b[M];int main(){ #ifndef ONLINE 阅读全文
posted @ 2013-05-23 20:49 心向往之 阅读(134) 评论(0) 推荐(0) 编辑