05 2013 档案

摘要:题意:n (n<=300)个村庄,要建设m (m<=30)个邮局,每个村庄使用最近的邮局,问总距离最小是多少?分析:最初的想法:dp(i, j)表示前j个村庄建设i个邮局,并且第i个邮局建设在第j个村庄的最小距离,则dp(i, j) = min ( dp(i-1,k) + dist(k,j) )。(i-1<=k<j, dist(k,j)为在村庄k和村庄j建设邮局,k和j之间的村庄到他们的最小距离)。由于n>=m,即最优解一定建设了m个邮局,第m个邮局可能建设在第k(m<=k<=n)个村庄,k+1~n的村庄只能到第k个村庄去,所以答案为min ( dp( 阅读全文
posted @ 2013-05-30 16:22 心向往之 阅读(159) 评论(0) 推荐(0)
摘要:题意:IOI99 花店橱窗布置 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定的,从左到右按1到V顺序编号,V是花瓶的数目。花束可以移动,并且每束花用1到F的整数标识。如果I < J,则花束I必须放在花束J左边的花瓶中。例如,假设杜鹃花的标识数为1,秋海棠的标识数为2,康乃馨的标识数为3,所有花束在放入花瓶时必须保持其标识数的顺序,即杜鹃花必须放在秋海棠左边的花瓶中,秋海棠必须放在康乃馨左边的花瓶中。如果花瓶的数目大于花束的数目,则多余的花瓶必须空,即每个花瓶只能放一束花。每个花瓶的形状和颜色也不相同,因此,当各个花瓶中放入不同的花 阅读全文
posted @ 2013-05-30 13:54 心向往之 阅读(592) 评论(0) 推荐(0)
摘要:题意:给一个N,求不超过N的哪个数的因子数最多,数目相同的取值小的那个。分析:反素数定义:g(i)表示 i 含有因子的数目,若小于x的任意数 i,都有 g(i)<g(x), 则x是一个反素数。反素数特性: x = 2^t1 * 3^t2 * 5^t3 * 7^t4 .....这里有 t1>=t2>=t3>=t4... t1>0 t2>0 t3>0...证明:如果ti<tj,其中i<j,由于pi小于pj,那么pi^tj*pj^ti<pi^ti*pj^tj,这样就出现了因子数目相同,但x更小的情况,与反素数的定义矛盾。然后搜索。。int 阅读全文
posted @ 2013-05-29 23:00 心向往之 阅读(138) 评论(0) 推荐(0)
摘要:题意:求C(a, b) 的约数个数。(a b<432)分析:C(a, b) = a! / b! / (a-b)!对于任意质数 p, n! 中有(n/p + n/p^2 + n/p^3 + ...)个质因子p。对于任意数 num = p1^a1 * p2^a2 *... pn^an ,其约数个数为(a1+1)*(a2+1)...(an+1)。int prime[100]={2,3,5,7...421,431,1000000};/*int s[1000005]={0};inline int cal(int n,int k){ int cnt=n/k; int sum=s[cnt]; ... 阅读全文
posted @ 2013-05-29 22:49 心向往之 阅读(168) 评论(0) 推荐(0)
摘要:题意:求第k个与m互质的数。分析:先求phi[m],区间[1, m]中有phi[m]个数与m互质。同样,在区间[ n*m +1, n*m +m ]中必然也有phi[m]个数与m互质,并且这phi[m]个数与[1 ~ m]的phi[m]个数是"一一对应"的。证明:设gcd(a + b, b) = p, p是a + b和b的公因子,那么p一定是a, b的公因子 (欧几里德。。)若k与m互质,假设k+m与m不互质,且其最大公约数为r,那么k与m必有公约数r,矛盾。。若k与m不互质,设其最大公约数为r,那么k+m与m必有公约数r,k+m与m不互质。 所以 “一一对应”。int m, 阅读全文
posted @ 2013-05-29 22:44 心向往之 阅读(160) 评论(0) 推荐(0)
摘要:题意:求大区间A B内离的最近和最远的两个素数,A B<=2,147,483,647。分析:先用大素数的线性筛法,预处理出1~sqrt(2,147,483,647)的所有素数,然后用 b[0] ~ b[B-A],来表示A+(0) ~ A+(B-A)的数是否是素数。。即若素数p*k = A+x --> A+x不是素数 --> b[x]=1 。#define Max 2147483647#define maxn 50000int prime[maxn],p;bool vis[maxn] ;void getPrime(int n){//大范围内素数的线性筛法 FOE(i,2,n){ 阅读全文
posted @ 2013-05-29 22:33 心向往之 阅读(121) 评论(0) 推荐(0)
摘要:题意:n组数a[i], b[i],令ti =C(a[i], b[i]) ,求t1 t2 t3....的最大公约数。分析:C(a, b) = a! / b! / (a-b)! ,记录最小的a[i], 设为min,则公因子不可能比min大。枚举公共素因子p, a!里p的个数为c1 = a/p+a/(p^2)+a/(p^3)..., b!里p的个数为c2,(a-b)!为c3,则一共有ci = c1-c2-c3个pc1 c2 c3...中最小值即为最大公约数中的p的个数。const int M = 9592;int prime[M]={2,3,5,7,11,13......99991};int a[1 阅读全文
posted @ 2013-05-29 22:19 心向往之 阅读(131) 评论(0) 推荐(0)
摘要:题意:无向图中有n个点,编号1~n,可以从一点走到相邻某点,也可以原地不动,这样得到一条路径的描述。例如下图所示的无向图中,路径[1 2 2 7 5 5 5 7 4]是错误的,因为2不能到达7, [1 2 245 5 5 7 4], [1 247 5 5 5 7 4], or [1 2 265 5 5 7 4]都是正确的,定义两条路径A和B的距离dist(A, B) = sum d(ai, bi) ,其中若ai==bi, d(ai, bi)=1 否则d(ai, bi)=0。。给定一条路径A,求一条正确路径B,使AB的距离 dist(A, B) 最小。分析:dp(i, v)表示第 i 步为点 . 阅读全文
posted @ 2013-05-29 21:26 心向往之 阅读(136) 评论(0) 推荐(0)
摘要:题意:一个棋盘,0表示没放棋子,1 2 3 4表示放了该颜色的棋子,每次选择一个棋子消掉,同时跟它相连的同色棋子也会被消掉,消掉棋子后形成空格0,空格上方的棋子会掉下来,填补空格。如果某列全为0,右边整体向左移,填补空列。分析:广搜 0ms每行最多6个数,每个数为0~4,将其转化成一个6位数。 最多6行,所以一个状态需要6个数来保存,这里我用了一个长度为6的一维数组。。每次从队列里取出一个状态,将其还原到二维数组里,取某棋子消掉,按要求填补空格得到新的二维数组,再将新数组进行压缩,入队列。int dx[] = {-1,0,1,0};//up Right down Leftint dy[] = 阅读全文
posted @ 2013-05-29 18:11 心向往之 阅读(291) 评论(0) 推荐(0)
摘要:题意:給一个字符串,把它分成许多子串,要求每个子串必须是回文串,问最少分成几个子串?分析:dp[i]表示1~i分成的最少子串数,dp[i] = min (dp[j-1] + 1),(j~i是回文).const int M = 1005;char s[M];int len;int c[M];//c[i]表示以1~i的最少回文个数int pre[2][M], p, q, x, y;//pre[][i]到i是一个回文,即pre[][i]是i所在回文的对称点//p q是滚动数组下标 x y是个数int main(){ #ifndef ONLINE_JUDGE freopen("in.... 阅读全文
posted @ 2013-05-29 13:56 心向往之 阅读(158) 评论(0) 推荐(0)
摘要:题意:魔王将在T时刻吃掉公主,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。如果骑士们在T时刻能找到公主就输出“YES”,否则输出“NO”。分析:简单广搜,要注意的是,一旦进入传输机就被传送到另一层,不能在传输机上停留。另外,若另一层的相对位置也是传输机,则不能传输,两个传输机都应视为墙。int dx[] = {-1,0, 阅读全文
posted @ 2013-05-28 20:15 心向往之 阅读(187) 评论(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 心向往之 阅读(180) 评论(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 心向往之 阅读(412) 评论(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 心向往之 阅读(129) 评论(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 心向往之 阅读(147) 评论(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 心向往之 阅读(120) 评论(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 心向往之 阅读(145) 评论(0) 推荐(0)
摘要:题意:6个数字,每次可以左移/右移光标,或将光标所在数字加一/减一,或将光标所在数字与第一个/第六个数字交换,问达到目标数字,最少需要多少次操作?分析:操作可以分成两部分考虑:移动光标和交换改变了原数字的位置,而加一减一改变数字的大小。先bfs出012345所能达到的所有状态,以及达到此状态光标经过了哪些数字。再针对新状态和目标状态,如果某一位数字不一样并且光标经过这一位,则可以改变此数字的大小,若没经过,则此状态无法达到目标状态。表达起来太费劲了,直接看代码吧。另外,据说左移操作是多余的,把代码中左移部分去掉,也AC了,但还是感觉有问题。。 有空再想吧。。const int M = 567; 阅读全文
posted @ 2013-05-26 20:46 心向往之 阅读(411) 评论(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 心向往之 阅读(181) 评论(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 心向往之 阅读(148) 评论(0) 推荐(0)
摘要:题意:n*m矩阵,从某一点起,向上下左右四个方向走,只能走到比自身值小的格子上,问最长路径的长度。分析:从小到大考虑每一个格子,dp[i][j]=max(dp[i-1][j], dp[i+1][j], dp[i][j+1], dp[i][j-1]) + 1, 其中 a[i][j]>a[x][y]。int dx[] = {-1,0,1,0};//up Right down Leftint dy[] = {0,1,0,-1};const int M = 105;int a[M][M], d[M][M];int n, m, ans;struct node{ int x,y;}nd[M*M];i 阅读全文
posted @ 2013-05-23 20:08 心向往之 阅读(129) 评论(0) 推荐(0)
摘要:题意:n种物品,第i种价值num[i],数量cnt[i],要将其尽量平分成两份,问这两份的价值各是多少?分析:多重背包的题,用母函数做的。输入数据以负数结束,但我看到样例最后一行是-1,就以为是以-1结束,TLE了半天。。。const int N = 50, M = 250000;int a[2][M+1], p, q, n, sum;int num[N+1], cnt[N+1];//值和个数int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); //freopen("out. 阅读全文
posted @ 2013-05-23 10:55 心向往之 阅读(155) 评论(0) 推荐(0)
摘要:题意:给定整数N,将其分成若干正数的和(正数可以相同),问有多少种方案?例如N=4,有: 4 = 4; 4 = 3 + 1; 4 = 2 + 2; 4 = 2 + 1 + 1; 4 = 1 + 1 + 1 + 1; 共5种方案。分析:(1+x+x2+x3...)*(1+x2+x4+x6...)*(1+x3+x6+x9...)....const int N = 120;int a[2][N+1], p, q;int n;void init(){ a[0][0] = 1; FOE(i, 1, N){ p = 1-q; FOE(j, 0, N) if(a[q]... 阅读全文
posted @ 2013-05-22 21:57 心向往之 阅读(130) 评论(0) 推荐(0)
摘要:题意:给定整数N,求有多少种方案,能将其分解为若干不同正数的和?(1<=N<=1000)例如N=4,有4=4,4=3+1两种, 4=2+2, 2重复,不满足条件。 4=3+1和4=1+3算一种。分析:(1+x)*(1+x^2)*(1+x^3)……(1+x^n),x^n的系数即为答案。const int mod = 19901014;const int N = 1000;int a[2][N+5], p, q;int n;void init(){ a[0][0] = 1; FOE(i, 1, N){ p = 1-q; FOE(j, 0, N) ... 阅读全文
posted @ 2013-05-22 21:25 心向往之 阅读(165) 评论(0) 推荐(0)
摘要:题意:给出1分 2分 5分硬币的个数,问最小的不能组合出的值是多少。const int M = 8005;int a[2][M], p, q, sum;int c[4], m[4]={0, 1, 2, 5};int main(){ #ifndef ONLINE_JUDGE //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif while(scanf("%d%d%d", &c[1], &c[2] 阅读全文
posted @ 2013-05-22 17:22 心向往之 阅读(141) 评论(0) 推荐(0)
摘要:题意:一条长为len(1<len<1,000,000,000)的河中,有n(1<n<50,000)块石头,移除m块,使具有最近距离的两块石头之间的距离最大。分析:二分,上界为len,下界为当前最近的石头的间距。对于二分的题目若求的是最大值,while(low <= high) ... if(check())... low=mid+1; else high=mid-1;若求的是最小值,while(low < high) ... if(check())... high=mid; else low=mid+1;答案均为 highconst int N = 5000 阅读全文
posted @ 2013-05-21 21:27 心向往之 阅读(129) 评论(0) 推荐(0)
摘要:题意:在n天里,Farmer John每天花a[i]元钱,把这些天分成连续的m份,要让最大的和尽量小,求这个和。分析:a[i]最大为max,总和为sum,则答案一定在max到sum之间。二分答案ans,遍历a[],若能将a[]分成m份,每份的总和<=ans,则ans为一个可行解,若ans可行,ans-1不可行,则ans为最终答案。const int N = 100005;int a[N];int n, m, low, high;bool check(int lim){ int cnt=1, temp=0; FOR(i, 0, n){ temp += a[i]; ... 阅读全文
posted @ 2013-05-21 19:22 心向往之 阅读(117) 评论(0) 推荐(0)
摘要:题意:给定一个整数n(1<n<2^31),求1~n的数与n的最大公约数之和,即∑gcd(i, n) (1<=i <=n) 。分析:枚举n的因数k,求有多少个 i ,使gcd(i,n)=k。设gcd(i,n)=k, 其中 i=ak, n=bk, 则gcd(ak, bk)=k => gcd(a,b)=1, 所以有φ(b)个 i ,使gcd(i,n)=k。答案为:∑k*φ(n/k) (k|n)#define Max 46355LL pri[Max], p, n;LL ans;bool vis[Max] ;void getPrime(LL n){//大范围内素数的线性筛法 阅读全文
posted @ 2013-05-21 16:56 心向往之 阅读(162) 评论(0) 推荐(0)
摘要:题意:求n个点的连通图个数。n=3时,有4个连通图分析:思路一:n个点的图的总个数为 2^C(n,2),假设点1所在的连通分量里有k个点,方案数为F(k) * C(n-1,k-1),其它n-k个点自由连接,有2^C(n-k,2)种情况,所以不连通的方案数为sum( F(k) * C(n-1,k-1) * 2 ^ C(n-k,2) ) ,答案为 F(n) =2^C(n,2) -sum( F(k) * C(n-1,k-1) * 2 ^ C(n-k,2) ) (1 <= k <= n-1)。思路二:去掉点1及其所有边后,假设点2所在连通分量里有k个点 (即在除去点1,2的其它点中选k-1 阅读全文
posted @ 2013-05-19 13:28 心向往之 阅读(157) 评论(0) 推荐(0)
摘要:题意:有n个点,问组成的三角形中,有多少个三角形的面积是整数。给出公式:A=|x1y2 - y1x2 + x2y3 - y2x3 + x3y1 - y3x1|/2。分析:当S = {x1y2, y1x2, x2y3, y2x3, x3y1, y3x1}里,有偶数个奇数项时,面积为整数。考虑三个点(x1,y1) , (x2,y2) , (x3,y3)坐标的奇偶性,发现有一个点x y奇偶性不同,另外两点的x y奇偶性相同,或者一点x y奇偶性相同,另外两点(x2,y2), (x3,y3)奇偶性不同且x2与x3奇偶性不同时,S里有奇数个奇数项,即面积不为整数。用0代表偶数,1代表奇数,当三点坐标为 阅读全文
posted @ 2013-05-18 20:28 心向往之 阅读(171) 评论(0) 推荐(0)
摘要:题意:n个数,取它们的三个排列a[] ,b[] ,c[],要求(a[i]+b[i])%n == c[i]%n分析:n是偶数无解,n是奇数:a[i]=b[i]=i,c[i]=(a[i]+b[i])%n。。。不会证明。。。 阅读全文
posted @ 2013-05-18 17:05 心向往之 阅读(134) 评论(0) 推荐(0)
摘要:题意:求A^B的所有因数的和(0 >= 1; } return ans;}int cal(int p, int n){//计算1+p+p^2+...+p^n if(!n) return 1; if(n&1) return cal(p, n/2)*(1+modexp(p, n/2+1)) % mod; else return (cal(p, n-1) + modexp(p, n)) % mod;}void solve(int n){ s = 1; for(int i = 0; pri[i] * pri[i] 1) s = s * cal(n,b) % ... 阅读全文
posted @ 2013-05-18 15:44 心向往之 阅读(172) 评论(0) 推荐(0)
摘要:题意:定义两个三元组(xi, yi, zi)和(xj, yj, zj),他们的距离为dist = max( xi-xj, yi-yj, zi-zj) - min(xi-xj, yi-yj, zi-zj),给定n个三元组(n<=200000),求任意两个三元组的距离之和。令a=xi-xj,b=yi-yj,c=zi-zj,问题转化为dist = max(a, b, c) - min(a, b, c),考虑数轴上的三个点a b c, dist为它们覆盖的线段长度。dist = ( |a-b| + |b-c| + |c-a| ) / 2。这样一来就不用考虑a b c 谁大谁小。。所以dist = 阅读全文
posted @ 2013-05-17 17:59 心向往之 阅读(249) 评论(0) 推荐(0)
摘要:两题都是基础题,不同的是 zoj 那题的男女可能重名。Gale-Shapley 算法:while ( 存在男人m是自由的 ) { 令w是m的还没求过婚的最高排名的女人 if ( w是自由的 ) m-w 配对 else { 取 w 的当前对象 m1 if ( w 更爱 m1 ) m保持自由 else m-w配对 m1变成自由 }}poj 3487const int N = 105;int n;int hm[N], hw[N]; //hm[i]为第i个男人的配偶 -1表示自由int a[N][N], b[N][N], p[... 阅读全文
posted @ 2013-05-16 18:02 心向往之 阅读(181) 评论(0) 推荐(0)
摘要:题意:‘H’是山地,‘P’是平原,在平原上可以放置炮兵,攻击范围为图中黑色部分,炮兵不能放置在其他炮兵的攻击范围内,问最多能放多少个炮兵?分析:用一个整数s表示一行的状态,s的第k位为1表示这一行第k列放置了炮兵。cnt[s] 表示 s的1的个数,即放置了炮兵的个数。d[r][i][j]表示第 r 行状态为 i, r-1 行状态为 j 的最大炮兵数,d[r][i][j] = max( d[r-1][j][k] + cnt[i] ); 其中j k 与 i 不冲突。每行最多有10个格子,状态为2^10,但有一些状态是非法的,合法状态在60个以内,所以要先预处理出所有合法状态。const int N 阅读全文
posted @ 2013-05-16 12:33 心向往之 阅读(146) 评论(0) 推荐(0)
摘要:题意:两个球,两个目标点,每次同时向 上下左右 移动这两个球,若前面是墙,则不动,两球不能重合,若一球到达目标点,另一球可从那里经过。。问最少多少步能将两球移动到目标点。分析:广搜,用四维数组f[x][y][u][v]记录两球坐标分别为x y , u v 时的最少步数。注意两球要同时移动,且不能重合,但一球在目标点,另一球可以与它重合。int dx[] = {-1,0,1,0};//up Right down Leftint dy[] = {0,1,0,-1};const int M = 25;const int N = 100005;int n,m,ans;char c[M][M];//地图 阅读全文
posted @ 2013-05-12 13:48 心向往之 阅读(135) 评论(0) 推荐(0)
摘要:题意:有n道题目,a[i][j] 表示做完第 i 道题再做第 j 道题所要花费的时间。Zty每次只做比以前做过的题目更难的题目,也就是说时间比以前的长。问最多能做多少道题。(每次都从第0题开始做,第0题花费时间为0).分析:简单深度搜索。。const int M = 15;int n, ans;int a[M][M];int b[M];void dfs(int i,int t,int cnt){//解决完第i题 最长时间t 已解决cnt道题目 checkmax(ans, cnt); FOR(j, 1, n){ //if(ans==n)return; if(... 阅读全文
posted @ 2013-05-11 12:47 心向往之 阅读(136) 评论(0) 推荐(0)
摘要:题意:有n (n<=15) 本高度不同的书,每次可以交换相邻的两部分书(多本),问最少多少次操作可以让书由小到大排列?如果次数>=5 输出5 or more,否则输出最少次数。分析:n!的状态空间太大,不能广搜,于是想到迭代加深搜索,又因为每次操作,最多改变3个后继值,最终状态每本书的后继都比自身大1,可以设计启发函数为 错误的后继值/3.另外在回溯的时候,假设本次交换的区间为[1,5] [6,8]那么还原状态应该交换[1,3] [4,8],而不能再次交换[1,5] [6,8]。。 1 2 3 4 5|6 7 8交换[1,5] [6,8]: 6 7 8|1 2 3 4 5交... 阅读全文
posted @ 2013-05-11 11:54 心向往之 阅读(177) 评论(0) 推荐(0)
摘要:题意:n×m的棋盘上,0表示空格,可自由通过,-1表示宝石,正数k表示有一个值为k的石头,不能通过。两人轮流玩游戏,每次可以将一个从棋盘外围有路径可以到达的石头的值减1,若减为0则变为空格,可自由通过。问最后谁能拿到宝石。分析:一开始以为是博弈,后来想想,发现如果甲将宝石外围的某石头(和宝石有路径相连的石头)变成了空格,则乙就能拿到宝石。所以他们只会选择和宝石不相通的石头,或者宝石外围的值大于1的石头。于是先广搜一次,把宝石外围的石头标记一下。再从棋盘外围广搜,遇到石头,若是宝石外围的石头,则ans += val-1,val为石头的值。若是其它石头,ans += val。为了方便,我 阅读全文
posted @ 2013-05-10 19:02 心向往之 阅读(205) 评论(0) 推荐(0)
摘要:题意:m×n的迷宫, ‘S’ 起点 ‘D' 终点 '.' 可以走 ‘X’ 墙 ‘1’~‘9’炸弹的数量,往上下左右走一步花费1秒钟,炸一面墙多花1秒钟,问最少多长时间能走到终点。分析:迷宫最大为8×8,可以用一个long long表示状态,走过的地方为1,没走过的为0. 然后广搜...判重用的map[64],map[i][state]表示在第i个格子,状态为state所用的最少时间。如果只用一个map 同时存储第 i 个格子和状态state,会超时。另外state第50位置1不能用state |= 1<<50, 1默认int型,左移50位 阅读全文
posted @ 2013-05-10 15:58 心向往之 阅读(152) 评论(0) 推荐(0)
摘要:题意:同poj 2283 给一个数字n,求n的倍数中,所使用不同数字最少的。例如1223含3个不同数字。如果有多个答案,取最小的。分析:对于任意n,最多两个数字就能组成n的倍数。因为a,aa,aaa……取n+1个,则必有两个模n余数相同,相减即得n的倍数。所以先考虑一个数字的情况,若没有n的倍数,再广搜两个数字。搜的时候要对余数判重,如果出现了相同的余数,则形成了循环。另外搜两个数字的时候,要枚举这两个数字再搜,同时搜10个数字会爆空间。const int M = 170000;int ans[M], pa;int a[M], p;//数字int b[M],pre[M];//余数 前驱int. 阅读全文
posted @ 2013-05-09 22:17 心向往之 阅读(225) 评论(0) 推荐(0)
摘要:题意:n种颜色的珠子可组成多少种长度为n的项链?(旋转算一种,不考虑翻转)n<1000000000,结果对p取余,p<30000分析:本题数据规模很大,若枚举旋转的长度会超时。假设旋转 i 步,则循环节个数为gcd( i, n ) (证明在这里) ,循环节长度 L = n / gcd(i, n). 则 L | n,可以枚举L,并计算gcd(i, n) = n / L的 i 的个数。设gcd(i, n) = t, i = kt,n = Lt, gcd(kt, Lt) = t 等价于 gcd(k, L)=1,这样的 k 有φ( L )个, 即 i 有φ( L )个。于是答案为 (1/n 阅读全文
posted @ 2013-05-03 14:43 心向往之 阅读(226) 评论(4) 推荐(0)
摘要:题意:用三种颜色的珠子串成长度为N(N<24)的项链,经过旋转和翻转所得的项链视为同一种项链,求共能组成几条不同的项链。分析:1、旋转:置换的个数是n个,第i个置换的循环节个数是gcd(n,i)个。证明:经过 LCM ( i ,n ) / i 次旋转回到自身,循环节的长度是 LCM( i , n ) / i ,n / ( LCM( i , n ) / i )就是循环节的个数,n / ( LCM( i , n ) / i ) = gcd( n , i )2、翻转:找循环节的关键是找对称轴,n要分奇偶性。当n = 2 * k + 1,对称轴就是每个点和圆心的连线,共n条,除了这个点没变,其他 阅读全文
posted @ 2013-05-02 16:30 心向往之 阅读(172) 评论(0) 推荐(0)
摘要:题意:给出两个数a和b,求出[a,b]之间,有多少个数为round number。round number的定义:其二进制数中0的数量大于或等于1的个数。分析:设round number有 s 位,则0的个数至少为 c= (s+1)/21. 若a的二进制有pa位,b有pb位,(pa<s<pb),s位的数中,第一位为1,其余s-1位可自由选择,所以有sum = C(s-1,c) +C(s-1,c+1 )+...+C(s-1,s-1 )。2. 和a位数相同且大于a的round number的个数为:将第一个0改为1,则后面的数位自由组合,满足round number条件的话,这个数一定 阅读全文
posted @ 2013-05-01 22:03 心向往之 阅读(188) 评论(0) 推荐(0)
摘要:题意:给一个字符串 S,长度<=10,其中的字母按升序排列。长度小的字符串比大的字符串靠前,长度相同按字典序排列,问 S 排第几个。a - 1b - 2...z - 26ab - 27...az - 51bc - 52...vwxyz - 83681分析:字母按升序排列,则选出若干字母,其排列唯一。先求长度len,比它短的字符串有C(26,1) + C(26,2) +...+C(26,len-1) 个。对于长度相同的字符串,设S=“ b d f h t ”,则前四位和 S 相同,最后一位小于 't' 并且大于 'h' 的有C('z'- 阅读全文
posted @ 2013-05-01 19:42 心向往之 阅读(133) 评论(0) 推荐(0)
摘要:题意:3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。给出初始状态和目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动方法。poj1077 hdu1043 zoj1217 uva652 sgu139 (15数码)首先,将空格看成数字9,对于任意的布局S,定义perm(S)为从上到下从左到右的一个排列,i的初始位置为(x,y) 目标位置为(x',y'),定义距离dist(i)=|x'-x| + |y'-y|,每移动一个棋子,dist(9)=dist(9)±1,dist( 阅读全文
posted @ 2013-05-01 13:39 心向往之 阅读(326) 评论(0) 推荐(0)