04 2012 档案

摘要:题目链接题目大意:给定一棵树,每个结点有一个权值,一棵树的权值为所有结点的权值和,现将这棵树分为两棵子树,要使得两子树的权值差最小。我的做法是先将无根树化为有根树,然后求每棵子树的权值,最后用一次扫描求结果。需要注意的是结果要用long long型。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 #define N 100000 5 #define MAX(a,b) ((a)>(b)?(a):(b)) 6 #define MIN(a,b) ((a)&l 阅读全文
posted @ 2012-04-27 22:18 BeatLJ 阅读(245) 评论(0) 推荐(0) 编辑
摘要:题目链接这题Balance Act那题差不多,不过这题的数据量更大,时间有点卡,我的O(N)的算法都跑了1100多MS(时限2S)。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 #define N 50005 5 #define MAX(a,b) ((a)>(b)?(a):(b)) 6 using namespace std; 7 vector<int> dep[N]; 8 int u[2*N],v[2*N],first[N],next[ 阅读全文
posted @ 2012-04-27 20:04 BeatLJ 阅读(217) 评论(0) 推荐(0) 编辑
摘要:题目链接题目大意:给定一棵树,树的每个结点有一个权值,每个结点的权值=去掉该结点后剩余的分支中结点最多的那个分支的结点数。求树中权值最小的结点。这题CE了两次,第一次因为使用了memset没包含头文件,第二次是因为GNU C++没有头文件<memory.h>,使用<string.h>就AC了。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 #define N 20000 5 #define MAX(a,b) ((a)>(b)?( 阅读全文
posted @ 2012-04-27 15:08 BeatLJ 阅读(292) 评论(0) 推荐(0) 编辑
摘要:题目链接这题要用左二子,右兄弟的存储结构来存树(附加一个结点0,将森林连成树),然后就是在二叉树上DP。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 205 5 int son[N],bro[N],w[N],n,m; 6 int c[N][N]; 7 void Insert(int u,int fa,int x) 8 { 9 w[u]=x;10 if(son[fa]==-1) son[fa]=u;11 els 阅读全文
posted @ 2012-04-27 09:50 BeatLJ 阅读(240) 评论(0) 推荐(0) 编辑
摘要:题目链接没有上司的晚会,经典的树形DP题。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 6000 5 int a[N],p[N],d[N],c[N],vis[N],sums[N],sumgs[N],dmax,n; 6 int fd(int k) 7 { 8 if(!vis[k]) return d[k]=0; 9 if(d[k]) return d[k];10 return d[k]=fd(p[k])+1;1 阅读全文
posted @ 2012-04-26 16:38 BeatLJ 阅读(217) 评论(0) 推荐(0) 编辑
摘要:1015 Jury Compromise1029 False coin1036 Gangsters1037 A decorative fence1038 Bugs Integrated, Inc.1042 Gone Fishing1050 To the Max1062 昂贵的聘礼1074 Parallel Expectations1080 Human Gene Functions1088 滑雪1093 Formatting Text1112 Team Them Up!1141 Brackets Sequence1143 Number Game1157 LITTLE SHOP OF FLOWER 阅读全文
posted @ 2012-04-26 13:14 BeatLJ 阅读(218) 评论(0) 推荐(0) 编辑
摘要:题目链接题目大意:给定一棵树,求最大点独立集中点的数目。这题昨晚一开始想到可以转化为求二部图的最大匹配来做,没估计复杂度,最后超时了。后来就考虑把树分成两部分,取结点较多的那部分作为结果,提交后WA。再后来,我考虑给树定一个根结点,然后分层,统计每层的结点数目,然后再转化为DP问题去做,相当于是分层DP,结果还是WA。昨天晚上躺在床上时,突然想到曾经听说过树形DP,难道这题正是?今天翻了下刘汝佳的白书,学习了下树形DP,然后果断AC。AC的代码 1 #include <stdio.h> 2 #include <vector> 3 #define MAX(a,b) ((a 阅读全文
posted @ 2012-04-26 12:45 BeatLJ 阅读(212) 评论(0) 推荐(0) 编辑
摘要:题目链接题目大意:给定一个只含1,2,3的数列,求排序的最小交换次数。这题说不出需要用什么算法,如果有的话,应该是贪心的思想。我的做法是,先统计1,2,3的个数,然后就知道了1,2,3应该排在哪些区间,首先将错位的两两交换(例如1在2的区间,2在1的区间),然后三个之间交换(例如1在2的区间,2在3的区间,3在1的区间)。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define N 1000 5 int a[N]; 6 in 阅读全文
posted @ 2012-04-25 20:39 BeatLJ 阅读(244) 评论(0) 推荐(0) 编辑
摘要:题目链接二分查找树的模拟。不能用数组模拟,那样内存会爆掉。View Code 1 #include <stdio.h> 2 #define N 1000 3 struct node 4 { 5 int x; 6 struct node *left,*right; 7 }node[N]; 8 char f; 9 void Insert(struct node *r,struct node *p)10 {11 if(!r) return;12 if(r->x>p->x)13 {14 if(r->left) Insert(r->left,p);15 else 阅读全文
posted @ 2012-04-25 19:59 BeatLJ 阅读(247) 评论(0) 推荐(0) 编辑
摘要:题目链接典型的DFS题,骑士周游问题。这题的关键在于字典序输出路径,要处理好搜索的顺序,另外需要注意的是,字母表示行,数字表示列。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define N 26 4 int dx[8]={-2,-2,-1,-1,1,1,2,2}; 5 int dy[8]={-1,1,-2,2,-2,2,-1,1}; 6 char vis[N][N],ok; 7 int n,m; 8 int ans[N]; 9 void dfs(int i,int j,int cnt)10 {11 i 阅读全文
posted @ 2012-04-25 17:15 BeatLJ 阅读(301) 评论(0) 推荐(0) 编辑
摘要:题目链接宽度优先搜索。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #include <queue> 4 #define N 300 5 using namespace std; 6 typedef pair<int,int> node; 7 queue<node> Q; 8 int dx[8]={1,1,-1,-1,2,2,-2,-2}; 9 int dy[8]={2,-2,2,-2,1,-1,1,-1};10 int n;11 int step[N][N];12 in 阅读全文
posted @ 2012-04-25 14:27 BeatLJ 阅读(207) 评论(0) 推荐(0) 编辑
摘要:题目链接动态规划题。题目大意:给定一个二维数组,数组中每个数代表一个高度,每次只能向相邻且高度下降的方向移动,求最长的移动距离。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 100 5 int dx[4]={0,0,1,-1}; 6 int dy[4]={1,-1,0,0}; 7 int h[N][N],n,m; 8 int c[N][N]; 9 int dp(int i,int j)10 {11 int n 阅读全文
posted @ 2012-04-25 13:52 BeatLJ 阅读(166) 评论(0) 推荐(0) 编辑
摘要:题目链接优先队列的题。进行队列弹出操作时要注意判空,如果有多case,记得清空队列。View Code 1 #include <stdio.h> 2 #include <queue> 3 #define N 30000 4 using namespace std; 5 6 priority_queue<int,vector<int>,greater<int> >qmin; 7 priority_queue<int,vector<int>,less<int> >qmax; 8 9 int a[N];1 阅读全文
posted @ 2012-04-25 09:42 BeatLJ 阅读(220) 评论(0) 推荐(0) 编辑
摘要:题目大意:给定一个n*m的只含0和1的矩阵,从矩阵的最后一行中的某个1出发,每步只能走到相邻的且是1的格子中,求能达到的最大高度(最小行数)。这题直接DFS即可,复杂度为O(N*M)。View Code 1 #include <stdio.h> 2 #define MAX(a,b) ((a)>(b)?(a):(b)) 3 #define N 100 4 int dx[4]={0,0,1,-1}; 5 int dy[4]={1,-1,0,0}; 6 char g[N][N]; 7 int n,m,ans; 8 void dfs(int i,int j) 9 {10 int d, 阅读全文
posted @ 2012-04-24 20:17 BeatLJ 阅读(290) 评论(2) 推荐(0) 编辑
摘要:题目链接贪心题,也是训练优先队列的好题。题目大意:给一块长木板,现要将其锯成n段,共需锯n-1次,每次锯的代价为所锯木板的长度,求最小总代价。其实也可以看成是把n段木板拼成一块,每次拼的代价为所拼木板的长度和。这就跟哈夫曼编码一样,每次选取两个最小的来拼。具体实现时用优先队列。View Code 1 #include <stdio.h> 2 #include <queue> 3 using namespace std; 4 #define INF 0x7fffffff 5 priority_queue<int,vector<int>,greater&l 阅读全文
posted @ 2012-04-24 15:05 BeatLJ 阅读(745) 评论(0) 推荐(0) 编辑
摘要:题目链接有限制的单源最短路。题目大意:给定一个图,图中的每条边有一个长度和一个费用,给出最大费用,求在不超过最大费用的前提下的最短路(从s到e)。我的解法是BFS+优先队列,我们可以把<d,t,i>看成状态,i为结点编号,d为结点到源点的距离,t为目前剩余的费用,每次BFS时都选取d最小的状态进行扩展,直到到达目标结点。一开始,我还担心内存会爆掉,但是一下也没想到其他方法,就照这个想法写了,结果居然AC了。由于要用到优先队列,所以只好临时学了一点STL,第一次提交是忘改用c++提交,CE了一次。View Code 1 #include <stdio.h> 2 #incl 阅读全文
posted @ 2012-04-24 13:54 BeatLJ 阅读(318) 评论(0) 推荐(0) 编辑
摘要:题目链接递推题,A[i]=A[i-1]+2*A[i-2]。需要注意的是要用long long型。View Code 1 #include <stdio.h> 2 #define N 64 3 long long a[N]; 4 int main() 5 { 6 int i; 7 a[0]=a[1]=1; 8 for(i=2;i<N;i++) a[i]=a[i-1]+(a[i-2]<<1); 9 while(~scanf("%d",&i)) printf("%lld\n",a[i-1]);10 return 0;11 阅读全文
posted @ 2012-04-23 17:07 BeatLJ 阅读(132) 评论(0) 推荐(0) 编辑
摘要:题目链接单源最短路的变形,需要很好的理解dijkstra最短路算法的思想。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define MAX(a,b) ((a)>(b)?(a):(b)) 5 #define N 1000 6 int g[N][N],w[N],n,m; 7 char vis[N]; 8 void dijkstra() 9 {10 int i,v,k,max;11 memset(vis,0,sizeof(v 阅读全文
posted @ 2012-04-23 16:32 BeatLJ 阅读(190) 评论(0) 推荐(0) 编辑
摘要:题目链接最短路,直接dijkstra水之,注意重边。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define N 1000 5 #define INF 100000 6 int g[N][N],dist[N],n,m; 7 char vis[N]; 8 void dijkstra() 9 {10 int i,v,k,min;11 memset(vis,0,sizeof(vis));12 for(i=0;i<n;i++) 阅读全文
posted @ 2012-04-22 17:21 BeatLJ 阅读(171) 评论(0) 推荐(0) 编辑
摘要:题目链接最短路的题,这题时间限制较严,第一次用dijkstra果断挂掉,后来改用SPFA写,由于我用的数据结构是动态链表,所以还是TLE,改为静态链表后就AC了。在这个过程中还贡献了一次WA,因为最后结果用32位会溢出,题中说的总价格不会超过1000000000是单个最短路不会超,而最后的结果是n-1个结点的最短路之和。View Code 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <memory.h> 4 #define INF 1000000001 5 #define N 1000001 6 阅读全文
posted @ 2012-04-22 16:13 BeatLJ 阅读(288) 评论(0) 推荐(0) 编辑
摘要:题目链接最短路的题,直接用dijkstra即可。此题比较有技巧性的地方在数据读入的处理,题中给出的是邻接矩阵的下三角,其中不直接邻接的边用字符x表示,其他地方用整数表示边长。具体做法见代码(参考了discuss)。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define MAX(a,b) ((a)>(b)?(a):(b)) 5 #define N 101 6 #define INF 0x7ffffff 7 int g[ 阅读全文
posted @ 2012-04-22 14:09 BeatLJ 阅读(991) 评论(0) 推荐(0) 编辑
摘要:题目链接最短路的题,与一般的最短路不同的是,建图后每个结点有一个等级值(一个非负整数),要求最短路并且路线上的结点的最大等级差不超过给定值。这题一开始我想到的就是枚举等级区间,在对应区间内用dijkstra求最短路,复杂度是L*N2,L是给定的最大等级差,N为结点数,由于题中L的最大值没有给出,所以我担心会超时,写好后提交是WA而不是TLE,这也让我确定了此法的可行性。经检查发现导致WA的错误:1.建图错误,按题意应建有限图;2.有一个两重循环的下标重复了;3.松弛的时候忘了检查结点等级。View Code 1 #include <stdio.h> 2 #include <s 阅读全文
posted @ 2012-04-22 13:40 BeatLJ 阅读(257) 评论(0) 推荐(0) 编辑
摘要:题目链接并查集的题,食物链模型。题目大意:已知关于n个数的m条信息,信息有两类,一类是已知Ai比Aj大K,另一类是已知Ai为K,问是否能从这m条信息中唯一确定这n个数,或者能推出矛盾。View Code 1 #include <stdio.h> 2 #define N 10001 3 #define M 20001 4 int p[N],c[N],v[N]; 5 int a[M],b[M],cnt; 6 char vis[N]; 7 int n,m; 8 void make_set() 9 {10 int i;11 for(i=0;i<n;i++) p[i]=i,c[i... 阅读全文
posted @ 2012-04-22 10:09 BeatLJ 阅读(332) 评论(0) 推荐(0) 编辑
摘要:最短路径大体分为2种,单源最短路径和多对顶点之间的最短路径;导论上一句话写的比较好:边的权值还可以被解释为其他的某种度量标准,而不一定是距离。它常常被用来表示时间、费用,罚款,损失或者任何其他沿着一条路线性积累的和我们试图将其最小化的某个量;最短路径还和dp有一定的关系;因为他符合最优子结构和公共子问题;例如Floyd就是一种动归的解法;常用的求最短路的算法是Dijkstra算法A*算法 SPFA算法Bellman-Ford算法 Floyd-Warshall算法 Johnson算法 而各个算法的基本思想都是松弛,松弛是改变最短路径和前驱的唯一方式;上面的算法之间的区别在于对每条边进行松弛操作的 阅读全文
posted @ 2012-04-21 15:39 BeatLJ 阅读(791) 评论(0) 推荐(0) 编辑
摘要:题目链接枚举题。第一次WA可能是因为读数据时用了getchar()吸收回车。View Code 1 #include <stdio.h> 2 #define N 1005 3 char map[N][N]; 4 int n,m; 5 char equal(char a,char b,char c) 6 { 7 return (a==b&&b==c); 8 } 9 char is_combo()10 {11 int i,j;12 for(i=0;i<n;i++)13 {14 for(j=0;j+2<m;j++) if(equal(map[i][... 阅读全文
posted @ 2012-04-21 14:53 BeatLJ 阅读(261) 评论(0) 推荐(0) 编辑
摘要:题目链接求单源最短路的题,因为边权非负,所以可以用dijkstra。这题有一点需要注意的地方是有重边,在读数据时取较小的即可。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define N 200 5 #define INF 2000000 6 int g[N][N]; 7 int dist[N]; 8 int n,m; 9 char vis[N];10 void dijkstra(int u)11 {12 int i,min 阅读全文
posted @ 2012-04-20 23:06 BeatLJ 阅读(223) 评论(0) 推荐(0) 编辑
摘要:题目链接这题与HDOJ1879有点不太一样,不能把不符合条件的边看成是已经修好的,使用克鲁斯卡尔时,碰到不符合的边直接跳过即可。View Code 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 #define D(x1,y1,x2,y2) (sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))) 5 #define N 101 6 #define M 5000 7 int x[N],y[N]; 8 struct node 9 {10 int a,b;11 阅读全文
posted @ 2012-04-20 22:21 BeatLJ 阅读(210) 评论(0) 推荐(0) 编辑
摘要:题目链接最小生成树的题。克鲁斯卡尔算法。View Code 1 #include <stdio.h> 2 #define N 100 3 #define M 5000 4 struct node 5 { 6 int a,b,d; 7 }edge[M]; 8 int n; 9 int p[N];10 void make_set()11 {12 int i;13 for(i=1;i<=n;i++) p[i]=i;14 }15 int find_set(int i)16 {17 return i==p[i]?p[i]:(p[i]=find_set(p[i]));... 阅读全文
posted @ 2012-04-20 21:23 BeatLJ 阅读(207) 评论(0) 推荐(0) 编辑
摘要:题目链接最小生成树的题。我用的克鲁斯卡尔算法。View Code 1 #include <stdio.h> 2 #define N 100 3 #define M 5000 4 struct node 5 { 6 int a,b,d; 7 }edge[M]; 8 int n,m; 9 int p[N];10 void make_set()11 {12 int i;13 for(i=1;i<=n;i++) p[i]=i;14 }15 int find_set(int i)16 {17 return i==p[i]?p[i]:(p[i]=find_set(p[... 阅读全文
posted @ 2012-04-20 21:07 BeatLJ 阅读(232) 评论(0) 推荐(0) 编辑
摘要:题目链接题目大意:给定n个整数,接下来有m个操作,操作分为两类,一类是修改操作:将第i个数改为k,另一类是查询操作:询问i,j之间第k大的数是多少。对于每个查询操作输出结果。如果没有修改操作,可以直接用伴随数组来做。跟POJ2104那题一样。这里的关键是修改操作,如果每次修改后都进行排序的话,肯定挂掉,注意到我们这里每次只修改一个数,只需将修改的数排到正确的位置即可,可以使用链表实现。这题的纠结之处在于数据格式,读入处理不好可能会WA或者RE。View Code 1 #include <stdio.h> 2 #include <stdlib.h> 3 #define N 阅读全文
posted @ 2012-04-20 20:44 BeatLJ 阅读(282) 评论(0) 推荐(0) 编辑
摘要:题目链接动态规划或者记忆化深搜。View Code 1 #include <stdio.h> 2 #define N 1005 3 char a[N],b[N],c[N][N]; 4 int n; 5 char dfs(int left,int right) 6 { 7 int k=right-left+1; 8 char f1=0,f2=0; 9 if(left==0&&right==n-1) return 1;10 if(c[left][right]!=-1) return c[left][right];11 if(left>0&&b[k] 阅读全文
posted @ 2012-04-19 22:46 BeatLJ 阅读(212) 评论(0) 推荐(0) 编辑
摘要:题目链接这题题目是A simple problem,但这题可谓A的不简单,不知道WA了多少次!题目大意:给定一个数列,求最长的连续子数列,使得最大值与最小值之差不超过给定值。由于数据量比较大,暴力法复杂度为O(N),肯定挂掉。我的做法如下:在扫描的过程中,当发现一段数的最大值与最小值之差大于给定值时,设最小值与最大值下标分别为i,j(无大小关系),下一次扫描时则从MIN(i,j)+1开始,这样可以避免很多不必要的计算。具体实现时要用到单调队列,纠结之处在于把下标移动和队列头指针移动搞混了!这题还有一点需要注意的地方就是最大值减最小值可能溢出。下面的代码提交时需改数据类型。View Code . 阅读全文
posted @ 2012-04-19 20:13 BeatLJ 阅读(427) 评论(0) 推荐(0) 编辑
摘要:题目链接题目大意:给定3个已排序的数列,在每个数列中选一个数,记为x,y,x,使(x-y)2+(y-z)2+(z-x)2最小。具体解法是贪心。这题我无语了,就因为打错一个字母,WA了4次。还好在队友帮助下及时发现,否则还不知道要纠结多久……下面的代码提交时需改数据类型,防止溢出。View Code 1 #include <stdio.h> 2 #define MIN(a,b) ((a)<(b)?(a):(b)) 3 #define N 1000005 4 int a[N],b[N],c[N]; 5 int dist(int x,int y,int z) 6 { 7 retur 阅读全文
posted @ 2012-04-18 09:53 BeatLJ 阅读(217) 评论(0) 推荐(0) 编辑
摘要:题目链接单调队列练习题。题目大意:n个牛排成一列向右看,牛i能看到牛j的头顶,当且仅当牛j在牛i的右边并且牛i与牛j之间的所有牛均比牛i矮。设牛i能看到的牛数为Ci,求∑CiView Code 1 #include <stdio.h> 2 #define N 8000001 3 #define INF 0x7fffffff 4 int a[N]; 5 int q[N],front,rear; 6 int main() 7 { 8 int i,n; 9 long long ans;10 while(~scanf("%d",&n))11 {12 f... 阅读全文
posted @ 2012-04-18 09:47 BeatLJ 阅读(292) 评论(0) 推荐(0) 编辑
摘要:题目链接求逆序数的题。因为只有4种元素,所以可以直接统计排在某个元素前面且比它小的元素个数(用4个变量记录已出现的A,C,G,T的个数),复杂度为O(N)。若元素种类很多,可以使用树状数组进行类似基数排序的统计。View Code 1 #include <stdio.h> 2 #include <stdlib.h> 3 #define N 55 4 #define M 105 5 struct node 6 { 7 char s[N]; 8 int d; 9 }node[M];10 int a,c,g,t,len;11 int cal(char s[])12 {13 . 阅读全文
posted @ 2012-04-18 08:56 BeatLJ 阅读(338) 评论(0) 推荐(0) 编辑
摘要:题目链接经典单调队列题。View Code 1 #include <stdio.h> 2 #define N 1000005 3 int a[N]; 4 int q[N],front,rear; 5 int main() 6 { 7 int i,n,k; 8 while(~scanf("%d%d",&n,&k)) 9 {10 for(i=0;i<n;i++) scanf("%d",&a[i]);11 front=rear=0;12 for(i=0;i<n;i++)13 {14 ... 阅读全文
posted @ 2012-04-17 20:04 BeatLJ 阅读(187) 评论(0) 推荐(0) 编辑
摘要:今天早上雨下的特别大,在去比赛的路上鞋和裤腿全湿透了。不过最后拿了第五名(二等奖)也值了。在比赛的过程中,我们队的配合还是很默契的,虽然一上来不在状态,前半个小时一直没提交,而旁边一个队伍神速AC了两题,真是压力山大,不过我们三人都没有慌,相互鼓励,沉着冷静,最终AC了5题,也超过了旁边队伍的4题。现在来看,我们今天的运气不错,在算法导论上找到一个类似算法AC了一题,但也还是有些许遗憾,最终我们排在第五名,而一等奖只取前4名,要是我最后那题能绝杀,今天就完美了。总而言之,这个结果还算不错,跟我们的期望差不多。这次比赛也算是我们组队以来的第一场正式比赛吧,能获奖确实是对我们最大的鼓励,也算是一个 阅读全文
posted @ 2012-04-15 23:35 BeatLJ 阅读(297) 评论(0) 推荐(1) 编辑
摘要:题目链接题目大意,给定一个整数序列a[N],询问区间ai到aj之间第k大的数是多少。共m次询问,对每次询问输出结果。此题可用伴随数组处理。具体做法是在输入的时候用一个数组保存每个数的序号,我们称这个数组为伴随数组,输入完成后,对数组进行排序,但对应的序号不变(用结构体将该数及其序号绑定,然后对结构体排序)。上面这个过程可以看成是预处理,接下来,对于每个询问i,j,k,只需对排序后的数组扫描一次即可,碰到序号在i到j之间的就--k,直到k为0,此时对应的数即为所求。View Code 1 #include <stdio.h> 2 #define N 100000 3 struct n 阅读全文
posted @ 2012-04-13 23:16 BeatLJ 阅读(1073) 评论(0) 推荐(0) 编辑
摘要:题目大意,给定圆心在原点的一个圆内的2*n个整点,求由AX+BY=0(A,B均为-500到500的整数)确定的一条直线,使得直线两边的点一样多,点不允许在直线上。由于题中数据均为有限的小整数,且时限不严,所以直接枚举即可。View Code 1 #include <stdio.h> 2 #define N 100 3 int x[N],y[N]; 4 int main() 5 { 6 int i,n,a,b,cnt,ok; 7 while(scanf("%d",&n)&&n) 8 { 9 for(i=0;i<2*n;i++) sca 阅读全文
posted @ 2012-04-13 21:15 BeatLJ 阅读(497) 评论(0) 推荐(0) 编辑
摘要:题目链接题目大意:给定一个整数序列,求最长上升子序列的长度,并求最长上升子序列的个数。关键在于求个数,可以另设数组c[k]保存以a[k]结尾的最长子序列的个数。View Code 1 #include <stdio.h> 2 #define MAX(a,b) ((a)>(b)?(a):(b)) 3 #define N 1000 4 int h[N],f[N],c[N],n; 5 int main() 6 { 7 int i,j,ans,cnt; 8 while(~scanf("%d",&n)) 9 {10 for(i=0;i<n;i++) s 阅读全文
posted @ 2012-04-13 15:35 BeatLJ 阅读(331) 评论(0) 推荐(1) 编辑
摘要:题目链接题目大意:棋盘上有一个马和一个帅,现给定棋盘的大小及马和帅的位置,假定帅不能移动,求马最少在多少步之内能吃到帅。这题我WA了4次,第一个错误是没有考虑到帅可能会阻挡马的路线,第二个错误是初始化t[N][N]时不小心将两个循环中都写成了n,而棋盘的大小是n*m。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define INF 0x7fffff 5 #define N 20 6 #define M 401 7 struc 阅读全文
posted @ 2012-04-13 14:13 BeatLJ 阅读(348) 评论(0) 推荐(0) 编辑
摘要:题目链接题目大意:给出n个公寓的互相距离,选择在其中一个公寓楼下建食堂,要求食堂到最远的公寓的距离最短。使用floyd求最短路,最短距离存在dist[N][N]中,然后求每行的最大值,再在这些最大值中求最小值。View Code 1 #include <stdio.h> 2 #define MAX(a,b) ((a)>(b)?(a):(b)) 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define INF 0x7ffffff 5 #define N 100 6 int dist[N][N]; 7 int main() 8 { 9 i 阅读全文
posted @ 2012-04-13 10:30 BeatLJ 阅读(199) 评论(0) 推荐(0) 编辑
摘要:题目链接经典贪心算法题。题目大意,给定一个整数N(位数最多2000)和整数k,在N中删除k个数使得剩下的数组成的整数最小。需要注意的是结果不要输出前导0。贪心策略为:从高位到低位扫描,若存在递减区间,则将高位删除以消除递减区间,否则从低位删。具体操作时,可以设一个栈来保存从高位起还没删的数。不难发现最后的结果一定是一个不下降序列,由此可以想到用二分来优化。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define N 2005 阅读全文
posted @ 2012-04-13 10:07 BeatLJ 阅读(382) 评论(0) 推荐(0) 编辑
摘要:题目链接题目大意,给定一个整数表达式A1/A2/A3/.../An,('/'为除号1<=n<=10000,1<=Ai<=1000000000),问是否能通过添加括号使得表达式的值为整数。咋一看似乎没思路,但仔细想,不难发现这里存在最优策略,最优策略是用一个括号将表达式变成A1/(A2/A3/.../An)。证明如下:n为1时,直接输出"YES",n大于1时,首先,A2一定为分母,无论如何添加括号都无法改变这个事实,其次,按照上面的策略加括号后,只有A2为分母,所以这是个最优策略。有了最优策略后,我们需要做的就是不断约分(求最大公约数) 阅读全文
posted @ 2012-04-13 09:51 BeatLJ 阅读(202) 评论(0) 推荐(0) 编辑
摘要:最基础的最小生成树,简单题。View Code 1 #include <stdio.h> 2 #include <math.h> 3 #include <stdlib.h> 4 #define D(x1,y1,x2,y2) (sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))) 5 #define N 100 6 #define M 5000 7 struct node 8 { 9 int a,b;10 double d;11 }edge[M];12 int n,m;13 double x[N],y[N];14 int p[M];15 阅读全文
posted @ 2012-04-12 22:59 BeatLJ 阅读(286) 评论(0) 推荐(0) 编辑
摘要:用floyd求最短路,难得的一次ACView Code 1 #include <stdio.h> 2 #define MIN(a,b) ((a)<(b)?(a):(b)) 3 #define N 20 4 #define INF 0x7fffff 5 int dist[N][N]; 6 int main() 7 { 8 int i,j,k,x,kase=0; 9 while(1)10 {11 for(i=0;i<N;i++)12 for(j=i+1;j<N;j++) dist[i][j]=dist[j][i]=INF;13... 阅读全文
posted @ 2012-04-12 22:21 BeatLJ 阅读(153) 评论(0) 推荐(0) 编辑
摘要:题目链接题目大意是给定一个有向图,求最少需添加多少条有向边使得原图强连通。可以先求强连通分量,统计缩点后的图中入度为0的点和出度为0的点,答案就是两者中的较大者,需要注意的是当原图是强连通时,直接输出0。因为没有初始化WA了一次。#include <stdio.h>#include <string.h>#define CLR(a) (memset(a,0,sizeof(a)))#define N 100char g[N][N],vis[N];int n;int ord[N],id[N],cnt,din[N],dout[N];void dfs(int u){ int v; 阅读全文
posted @ 2012-04-10 22:12 BeatLJ 阅读(220) 评论(0) 推荐(0) 编辑
摘要:题目链接由于之前没写过网络流方面的题目,所以第一次写的时候居然想到用动态规划去做(在没有环的情况下貌似可以,有环会RE)。现在看来,这题是个求最小割的题,因为最大流量最小割相等,所以也就是求最大流量。容量网络也很明显。我用的是标号法(Edmonds-Karp算法)。#include <stdio.h>#include <string.h>#define N 152#define INF 0x7fffffff#define MIN(a,b) ((a)<(b)?(a):(b))int c[N][N],flow[N][N],a[N],p[N],f,n,m;int que 阅读全文
posted @ 2012-04-09 23:20 BeatLJ 阅读(239) 评论(0) 推荐(0) 编辑
摘要:题目链接并查集的题。一开始的时候没看懂题,以为要用最短路算法去做,结果样例都没过,后在队友的指导下终于理解了题意。用并查集写好后,第一次提交莫名奇妙的RE,检查后发现查函数没写返回值(编译器没提示呢?而且样例也过了),第二次提交是WA,经检查后发现是无穷大设得不够大。下次一定要注意这些细节问题。#include <stdio.h>#define N 10005#define INF 0x7fffffffint p[N],d[N],out[N],n;void make_set(){ int i; for(i=0;i<=n;i++) p[i]=i,d[i]=0,out[i]=0; 阅读全文
posted @ 2012-04-08 20:23 BeatLJ 阅读(376) 评论(0) 推荐(0) 编辑
摘要:题目链接动态规划题,LCS的变形。无语了,写错两个字母,WA了3次啊!#include <stdio.h>#include <string.h>#define MAX(a,b) ((a)>(b)?(a):(b))#define N 105int m[5][5]={ 5,-1,-2,-1,-3, -1,5,-3,-2,-4, -2,-3,5,-2,-2, -1,-2,-2,5,-1, -3,-4,-2,-1,-10000};char a[N],b[N],vis[N][N],la,lb;int c[N][N];int f(int x,int y){ int i,... 阅读全文
posted @ 2012-04-07 23:32 BeatLJ 阅读(136) 评论(0) 推荐(0) 编辑
摘要:题目链接题目大意,给定一个字符串,求至少需插入多少字符使其变成回文。动态规划题。#include <stdio.h>#include <memory.h>#include <string.h> #define MIN(a,b) ((a)<(b)?(a):(b)) #define N 5001 char s[N]; int c[N]; int main() { int i,j,n,a,b; while(scanf("%d",&n)!=EOF){ getchar(); gets(s); for(i=n-2;i>=0;i-- 阅读全文
posted @ 2012-04-07 20:11 BeatLJ 阅读(269) 评论(0) 推荐(0) 编辑
摘要:题目链接题目的模型为给定含m个数的数列,将其分为连续的n段,使每段的和的最大值最小(刘汝佳白书上有)。由于是连续的,题目就简单了,之前就是没注意到这点,想了好久都没思路。我们可以首先可以确定结果的上界和下界,然后使用二分法将这个区间不断缩小,这个过程中要判断对于一个给定的x,是否能够在x天内修完路,因为路段是连续的,所以可以使用贪心来判断,贪心策略为,从第一个数开始,将尽量多的数分配到第一段,以此类推,直至分配完成,若分配的段数大于n则无法在x天内完成,否则可以。 1 #include <stdio.h> 2 #define MAX(a,b) ((a)>(b)?(a):(b) 阅读全文
posted @ 2012-04-07 19:49 BeatLJ 阅读(232) 评论(0) 推荐(0) 编辑
摘要:题目链接经典DP问题。由于最初if(c[i][j]>=0) return c[i][j];一句中少写一个等于号造成TLE,查了好久啊……View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 300 5 char a[N],b[N]; 6 int c[N][N]; 7 int f(int i,int j) 8 { 9 if(i<0 || j<0) return 0;10 if(c[i][j]>= 阅读全文
posted @ 2012-04-06 21:33 BeatLJ 阅读(304) 评论(0) 推荐(0) 编辑
摘要:题目链接简单DP题。View Code 1 #include <stdio.h> 2 #define N 45 3 int c[N][2]; 4 int main() 5 { 6 int t,i,n; 7 c[1][0]=c[1][1]=1; 8 for(i=2;i<N;i++) 9 {10 c[i][0]=c[i-1][0]+c[i-1][1];11 c[i][1]=c[i-1][0];12 }13 scanf("%d",&t);14 for(i=1;i<=t;i++)15 {16 ... 阅读全文
posted @ 2012-04-06 17:39 BeatLJ 阅读(213) 评论(0) 推荐(0) 编辑
摘要:题目链接简单动态规划题。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define N 500002 4 #define MAX 10000000 5 char vis[MAX]; 6 int c[N]; 7 int main() 8 { 9 int n,i,tmp; 10 c[0]=0,vis[0]=1; 11 for(i=1; i<N; i++) 12 { 13 tmp=c[i-1]-i; 14 if(tmp>0&&!vis[tmp]) vis[tmp]=1,c[i]=tm 阅读全文
posted @ 2012-04-06 17:22 BeatLJ 阅读(340) 评论(0) 推荐(0) 编辑
摘要:题目链接简单的动态规划题,WA了4次居然是因为N太小,为自己的吝啬感到无语。View Code 1 #include <stdio.h> 2 #define N 21 3 int f[N][N][N]; 4 int w(int a,int b,int c) 5 { 6 if(a<=0 || b<=0 || c<=0) return 1; 7 if(a>20 || b>20 || c>20) return w(20,20,20); 8 if(f[a][b][c]>0) return f[a][b][c]; 9 if(a<b&&a 阅读全文
posted @ 2012-04-06 17:02 BeatLJ 阅读(219) 评论(0) 推荐(0) 编辑
摘要:题目链接经典的动态规划题(数塔)。View Code 1 #include <stdio.h> 2 #define MAX(a,b) ((a)>(b)?(a):(b)) 3 #define N 100 4 int a[N][N],f[N]; 5 int main() 6 { 7 int n,i,j; 8 while(scanf("%d",&n)!=EOF) 9 {10 for(i=0;i<n-1;i++)11 {12 for(j=0;j<i+1;j++) scanf("%d",&a[i][j]);13 ... 阅读全文
posted @ 2012-04-06 16:11 BeatLJ 阅读(199) 评论(0) 推荐(0) 编辑
摘要:题目链接此题初看起来是一个二分匹配的问题,一个国王有n个儿子,将要与n个女孩结婚,已知每个儿子喜欢某几个女孩,并给出了一个初始匹配,问题是求每个儿子可能与哪些他喜欢的女孩结婚,一旦他选一个结婚后,其他的儿子仍能选到自己喜欢的人结婚。若直接枚举个中可能,然后用匈牙利算法求完美匹配判断,这样的话时间复杂度是O(n5),毫无疑问会超时。在这里,题目给出里一个初始完美匹配,必须加以利用。我们可以把初始完美匹配中的每一对看成结点进行构图,因此每个结点包含一个男孩和一个女孩,若结点i中的男孩喜欢结点j中的女孩,就在结点i与结点j之间连一条有向边,这样问题就转化为求强分图,每个男孩可以与他喜欢的并且与他在同 阅读全文
posted @ 2012-04-04 22:12 BeatLJ 阅读(754) 评论(0) 推荐(0) 编辑
摘要:题目链接动态规划题。模型为给定一条直线上的n个整点坐标,在其中选取p个点作为警亭,使得其余的点到最近的警亭的距离之和最小(下面简称最小距离和)。对输入坐标排序后,用c[i][j]保存最后一个警亭设在第i点,且该点之前还有j个警亭的情况下,第一点到第i点的最小距离和。照此不难写出状态转移方程。c[i][j]=max{c[k][j-1]+(min(d[i]-d[t],d[t]-d[k]),t=k+1...i-1),k=j-1...i-1}View Code 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <s 阅读全文
posted @ 2012-04-04 17:56 BeatLJ 阅读(1237) 评论(0) 推荐(0) 编辑
摘要:POJ3177POJ3352把这两个题写到一起,是因为这两题完全一样,用下面的代码两个题都可以AC。题目大意是给一个无向连通图,求添加最少边数使原图变成双连通图。由于是第一次写双连通图的缩点,所以WA了5次,在WA到AC的过程中,发现的错误如下:1、深度优先数没有初始化;2、深度优先数初始化错误;3、桥的判断有误;4、输入数据有重边,使用邻接表存储没有跳过重边。下面写一下这题的主要思路,用数组dfn保存各个结点的访问顺序(深度优先数),数组low[k]保存结点k及其子结点通过回边能到达的所有结点的最小深度优先数(下面简称最小深度优先数)。若子节点的最小深度优先数大于父结点的最小深度优先数,则连 阅读全文
posted @ 2012-04-04 17:50 BeatLJ 阅读(467) 评论(0) 推荐(0) 编辑
摘要:题目链接简单的搜索题,深搜即可。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define CLR(a) (memset(a,0,sizeof(a))) 5 #define N 101 6 char g[N][N]; 7 int n,m,k,ans,tmp; 8 int dir[4][2]={1,0,0,1,-1,0,0,-1}; 9 void dfs(int i,int j)10 {11 int d,ni,nj;12 g[i 阅读全文
posted @ 2012-04-03 23:04 BeatLJ 阅读(234) 评论(0) 推荐(0) 编辑
摘要:题目链接动态规划题,题目大意,有n个城市,一个人从第一个出发,每天可以选择继续呆在当前城市或者转移到其他城市(可以把继续呆在当前城市看成从当前城市转移到当前城市),第i天呆在第j个城市的收入为in[i][j],从第i个城市转移到第j个城市的费用out[i][j],求m天后的最大收入。把第k天的收入与第k-1天的收入联系起来即可写出状态转移方程。用c[i][j]保存i天过后最后呆在城市j的总收入,c[i][j]=MAX(c[i-1][k]+in[i][j]-out[k][j],k=0,1,...n-1),注意到从第一个城市出发,所以边界为第一天结束时的收入。View Code 1 #inclu. 阅读全文
posted @ 2012-04-03 23:00 BeatLJ 阅读(277) 评论(0) 推荐(0) 编辑
摘要:题目链接题目的本质就是求最长不下降子序列,这是动态规划的典型,很容易写出O(n2)的算法,但由于MAX=40000,普通算法会超时,必须采用更快的算法。下面简单介绍求最长不下降子序列(可推广到其他类型)的O(nlogn)算法。假设数字序列为a[N](也可不用保存,一边读入一边处理),先介绍如何求以第一个元素开头的最长不下降子序列,我们会用到一个数组d[N],d[k]保存的是数组a中以第一个元素开头的所有长为k的不下降子序列最后一个元素的最小值(下面将简称为最小最后元素),显然d的长度len即为所求。而且容易用反证法证明这个数组是递增的,若存在i<j,且d[i]>d[j],可以这样想 阅读全文
posted @ 2012-04-03 22:31 BeatLJ 阅读(441) 评论(0) 推荐(0) 编辑
摘要:题目链接这题大意是给一个有向图,求至少给多少个结点发消息能使消息传遍整个网络,并进一步求出至少添加多少条边能使对图中任意一个结点发消息都能使消息传遍整个网络。可以先用kosaraju将强连通分支缩点,得到原图的基图,然后统计入度为0的连通分量个数和出度为0的连通分量个数,入度为0的必须给它发消息,入度不为0的不必给发消息,所以第一问所求即为缩点后的图中入度为0的个数,至于第二问,只需将入度为0的结点与出度为0的结点连接即可满足要求,最少需加边数目为两者之中的较大者,需注意的是,单只有一个连通分量时,输出结果为0 。这题第一次提及后TLE,原因竟是N不够大,为什么不是RE呢?View Code 阅读全文
posted @ 2012-04-02 16:05 BeatLJ 阅读(535) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示