摘要: 直接map就水过去了。。 1 #include <map> 2 #include <string> 3 #include <stdio.h> 4 #include <iostream> 5 using namespace std; 6 map<string,int> mp; 7 string s[5005],s1; 8 int cas,n,m,cc[]={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9}; 9 main(){10 for(cin>>cas;cas--; 阅读全文
posted @ 2012-09-14 11:53 Burn_E 阅读(132) 评论(0) 推荐(0)
摘要: 这题比较容易想到的做法是splay,但是splay写起来比较麻烦而且每次操作都有LogN的复杂度,双向链表也是可以实现的,但实践起来比较麻烦,尤其是翻转操作。。。 可以发现每次L或者R都是移动一位的,我们可以用更简单的数据结构来实现,用两个栈分别存L左边和R右边的数据,L和R中间的数据使用一个双端队列来保存,因为涉及到翻转操作,要用一个dir来表示当前的双端队列哪边是头哪边是尾。。。 对于题目中给出的七种操作,都可以在O(1)的复杂度内实现,为了描述方便,左栈代表L左边数的栈,右栈代表R右边数的栈。 1,MoveLeft L/R 左移左指针就是把左栈中栈顶的数弹到双端队列头部,左移... 阅读全文
posted @ 2012-09-14 11:51 Burn_E 阅读(376) 评论(0) 推荐(0)
摘要: 给出N个城市,城市之间的路径需要一定的花费。其中一些城市(H<=15)是必达的,在这些城市可以打工赚钱,但前提是有足够的钱购买这些城市的工作许可。问是否能获得所有的许可并且最终回到起点。 这题和我之前出过的一个题很像。。http://acm.csu.edu.cn/onlinejudge/problem.php?id=1175 先对这H个点做一遍最短路,这题的点比较少,直接用FLOYD,然后对这H个点用哈密顿回路DP就可以了。 需要注意的是一个城市允许经过多次,如果第一次来这个城市时不够钱购买工作许可可以在其他城市工作赚了钱之后再回来拿。。。 1 #include <string.. 阅读全文
posted @ 2012-09-14 11:24 Burn_E 阅读(232) 评论(0) 推荐(0)
摘要: 有一个栈,你可以把这个栈中的数吐到另一个栈中去,然后每次可以从两个栈中选择一个数出栈,使∑num[i]*(i-1)最小,num[i]代表第i个出栈的数。 比赛的时候一直没想法,看了解题报告才恍然大悟。。对于每个区间,枚举第一个人是第几个出栈的,假设区间是[L,R],第一个人是i个出栈的,那么这个栈就被分成了三部分,[L,L],[L+1,L+i],[L+i+1,R],对后面两个区间看作子问题继续DP,注意对后面一个区间要加上(sum[R]-sum[L+i-1])*i,sum[i]表示前缀和。 1 #include <stdio.h> 2 #include <string.h&g 阅读全文
posted @ 2012-09-14 11:12 Burn_E 阅读(200) 评论(0) 推荐(0)
摘要: 求X^Z+Y^Z+XYZ=K有多少正整数解。 对于Z=2时是完全平方数可以直接求解,Z=3~31时直接暴力枚举即可,对于所有的X^Y可以全部预处理出来,最多大概也就50000*31种组合。 其实确定了X和Z后,Y可以二分求解的,但当Z>=3时Y能取的值加起来也没有多少。。所以枚举就OK了。 1 #include <stdio.h> 2 #include <math.h> 3 #define MAXN 47000 4 typedef long long LL; 5 const LL INF=(1LL<<31); 6 LL p[47000][31],k; 阅读全文
posted @ 2012-09-14 10:43 Burn_E 阅读(181) 评论(0) 推荐(0)
摘要: 给出N个点,第一个点是裁判,其他N-1个点需要裁判过去回答问题,每个点需要的时间不一样,而每个裁判最多能回答M分钟的问题。题目分两问,第一问是如何分配可以使使用的裁判数最少,第二问是如何分配裁判,使裁判走过的总路程和最少,裁判一开始都在1,最终也要回到1。 至于第一问,用一个状态标记已经回答过的人,并用两个数组存回答这些人问题需要的最小裁判数以及裁判数最少时最后一个裁判的剩余时间,然后用类似哈密顿回路形式DP求解就可以了。 第二问,是MTSP(多旅行商)问题,先求出裁判走过每个集合最终回到起点所需走的路程,然后DP合并环即可。比如1~3三个点,裁判在1,那答案就是Min(1->2-> 阅读全文
posted @ 2012-09-14 10:38 Burn_E 阅读(588) 评论(0) 推荐(0)
摘要: 平面图网络流,比赛的时候想不到怎么建对偶图试了试dinic,居然水过去了。。数据是真水。。 赛后看了各牛的解题报告,才搞懂怎么建对偶图,确实是很巧妙。关于对偶图的概念,可以去看08年周东的论文《两极相通——浅析最大—最小定理在信息学竞赛中的应用》。 建对偶图的难点在于确定每条边相邻的是哪两个块,过程可分为四步 1、将无向图的每条边拆为两条有向边,然后扫描所有的点,将某边对于该点的入边ID和出边ID以及极角存起来。注意起点和终点之间也要连一条边。 2、将与该点相连的边按照极角排序,每条边的入边ID的next指向下一条边的出边ID。不难发现,这样操作以后,每个块周围的边形成了一个环,并... 阅读全文
posted @ 2012-09-14 10:26 Burn_E 阅读(503) 评论(0) 推荐(0)
摘要: 网赛第一个看的就是这题,直接打表找规律。很容易发现是由大于4的的偶数以及奇数的平方,再除去偶数的平方所组成。一开始犯了个比较2的错误,要不然应该是FB了。。 也没有去推为什么是这样,这种题目一般都是先打表找下规律,一发现规律就懒的去推了。。 直接sqrt是有精度问题的,但是G++能A,C++是WA,比较简单的办法是sqrt后再通过乘法调整一下。 1 #include <string.h> 2 #include <stdio.h> 3 #include <math.h> 4 typedef long long LL; 5 int cas; 6 LL l,r; 阅读全文
posted @ 2012-09-14 01:33 Burn_E 阅读(168) 评论(0) 推荐(0)
摘要: 8进制转10进制,只是对应位的数不一样。 1 #include <string.h> 2 #include <stdio.h> 3 int n; 4 int d[]={0,1,2,0,3,4,5,6,0,7}; 5 int main(){ 6 while(scanf("%d",&n),n){ 7 int sum=0,b=1,nn=n; 8 while(n)sum+=d[n%10]*b,b*=8,n/=10; 9 printf("%d: %d\n",nn,sum);10 }11 return 0;12 } 阅读全文
posted @ 2012-09-14 01:23 Burn_E 阅读(168) 评论(0) 推荐(0)