随笔分类 - ACM题解
摘要:维护一个整数序列,支持以下操作:1 x v : 将第x个整数的值修改为v;2 x y : 查询区间[x,y]之间的最小值;3 x y : 查询区间[x,y]之间的最大值;4 x y : 查询区间[x,y]内的整数和。数据保证查询结果均在int范围之内,但中间结果是否可能溢出呢?我交的程序没考虑这个也AC了。通过这题还发现一个奇怪的现象,用memset初始化的程序跑了2s多,而用for循环初始化的程序才跑468ms……for循环初始化(468ms)#include <stdio.h>#include <string.h>#define MIN(a,b) ((a)<(
阅读全文
摘要:维护一个整数序列,支持2种操作:1、修改:将给定区间中的每个数增加一个值;2、查询:查询给定区间中所有数的和。View Code #include <stdio.h>#define N 100010#define Node 800000int n,m,x[N];long long sum[N];int left[Node],right[Node];long long incsum[Node],inc[Node];void create(int i,int l,int r){ left[i]=l; right[i]=r; inc[i]=0; incsum[i]=0; ...
阅读全文
摘要:Description给出的表达式全为合法的四则运算表达式,含括号。Input每行一个表达式,数字全为int型整数,长度不超过100字符Output输出表达式的值,一律保留小数点后4位。Sample Input11+2-1+2-1+(-2) Sample Output1.00003.00001.0000-3.0000 代码写得很混乱……对于括号的处理,我用的是递归调用,对于运算符的优先级的处理,我是通过2遍扫描来完成的,第一遍计算乘除运算,第二遍计算加减运算。View Code #include <stdio.h>#include <string.h>#define N
阅读全文
摘要:DescriptionDr.Kong设计的机器人卡多非常爱玩,它常常偷偷跑出实验室,在某个游乐场玩之不疲。这天卡多又跑出来了,在SJTL游乐场玩个不停,坐完碰碰车,又玩滑滑梯,这时卡多又走入一个迷宫。整个迷宫是用一个N*N的方阵给出,方阵中单元格中填充了一个整数,表示走到这个位置的难度。这个迷宫可以向上走,向下走,向右走,向左走,但是不能穿越对角线。走迷宫的取胜规则很有意思,看谁能更快地找到一条路径,其路径上单元格最大难度值与最小难度值之差是最小的。当然了,或许这样的路径不是最短路径。机器人卡多现在在迷宫的左上角(第一行,第一列)而出口在迷宫的右下角(第N行,第N列)。卡多很聪明,很快就找到了
阅读全文
摘要:Description设S是一个合法的表达式,E为一个数字字符序列,则合法的表达式可以表示为:E, +E, -E, (S),+(S),-(S),S+(S),S-(S),S*(S),S/(S) 等。(E可以是全‘0’的字符串)。请注意+S, -S, S+S等不一定是合法的表达式,因为可能出现如“+-E”运算符相邻情况,另外出现“()”括号中没有元素的表达式也是不合法的。Input每行一个字符串,最长不超过1023个字符。可能有空行。Output如果表达式合法,输入“Yes”,否则输入“No”,然后换行。如果表达式为空,则输出一个空行。Sample Input-1+2+-1+2+(-1+2)()-
阅读全文
摘要:这题就是裸的最短路,而且边权都为非负,可以直接用dijkstra来求。写这题主要是为了练习一下dijkstra的优先级队列实现,提交后运行时间为63MS,比一般的dijkstra快一点(97MS)。后来又尝试用SPFA写,结果还是63MS。在写dijkstra的优先级队列实现和SPFA的过程中发现,这两个算法非常类似,不过,SPFA用的是一般的队列。SPFA #include <stdio.h>#include <string.h>#include <queue>using namespace std;#define MIN(a,b) ((a)<(b)
阅读全文
摘要:求欧拉道路的题,可能是回路,也可能不是回路,若存在奇度点,则应从奇度点开始找路径,为保证最后的路径是字典序最小的,找路径时必须遵循小结点优先的原则。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 501 5 int n,m,g[N][N],d[N],path[N],top; 6 void dfs(int u) 7 { 8 int v; 9 for(v=1;v<=n;v++)10 {11 if(g[u...
阅读全文
摘要:Description在一个8行9列的国际象棋棋盘上,有一名骑士在追杀对方的国王。该骑士每秒跨越一个2*3的区域,如下图所示。而对方的国王慌忙落逃,他先沿着右下斜线方向一直跑,遇到边界以后会沿着光线反射方向继续跑(遇到死角则原路返回),他每秒只跑一格。给出骑士和国王的初始位置,求最快在多少秒的时候骑士能追杀掉对方的国王。骑士和国王每一秒都必须要有行动,而不能原地等待。Input有多组测试数据。对于每组测试数据,输入只有一行:nx,ny,kx,ky,前2个表示骑士的初始坐标,后2个表示国王的初始坐标,以左上角的格子为(0,0),向右为x轴正方向,向下为y轴正方向。(0<=nx,kx<
阅读全文
摘要:求一棵树中2个点的最近公共祖先。我的做法:用并查集求出每个结点的深度,然后递归求最近公共祖先。View Code 1 #include <stdio.h> 2 #define N 10001 3 int fa[N],p[N],d[N],n; 4 void make_set() 5 { 6 for(int i=1;i<=n;i++) 7 { 8 p[i]=i; 9 d[i]=0;10 }11 }12 int find_set(int i)13 {14 int pi=p[i];15 if(pi!=i) p[i]=find_set(p[i]);16 if(p...
阅读全文
摘要:Description中南大学ACM的暑期集训马上就要开始了,这次集训会将全体N名集训队员(编号分别为1, 2, …, N)按集训选拔赛的排名分成两组,前K名队员分入A组,其余队员分入B组。但现在助理教练CSGrandeur一不小心把集训选拔赛的排名弄丢了,而之前又没将A组和B组的人员确定出来,于是CSGrandeur打算问一下集训人员他们的名次各是怎样的,以此来确定一下A组的队员。然而集训队员们都视名次如粪土,只是隐约记得某些人排在了自己的后面,最终反馈到CSGrandeur这里的一共有M条信息,每条信息都可以用一个二元组(x, y) (x!=y)表示,含义为第x名队员记得第y名队员的排名比
阅读全文
摘要:最近在写遗传算法求TSP时看到了grefenstette编码,于是想起了这个题目,这题我原来是用线段树写的C语言提交的,用时157ms,刚用树状数组+二分写用C++提交只跑了47ms,感觉快了不少。这题数学模型是:现有一个1到n的一个被打乱的排列,告诉你每个数的左边有多少个数比它小,显然第一个数左边没有比它小的数,求每个位置上的数。grefenstette编码差不多,只是把左边改成了右边再加1,例如:8 6 7 5 3 4 1 2编码后是:8 6 6 5 3 3 1 1View Code 1 #include <stdio.h> 2 #include <string.h>
阅读全文
摘要:BFS基础题View Code 1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #define N 201 5 #define INF 0x7fffffff 6 using namespace std; 7 queue<int> Q; 8 int d[N],t[N],n,a,b,cur,next; 9 char inq[N];10 void bfs()11 {12 for(int i=1;i<=n;i++) t[i]=INF;13 memset(inq,0,si
阅读全文
摘要:题目大意:给定n个正整数,问能否分成4组,且每组的和相等。分析:这题就是sticks那题的简化版。思路一样。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <vector> 5 #define N 20 6 using namespace std; 7 vector<int> edge[4]; 8 int len[N],n,sum; 9 char vis[N],yes;10 int cmp(const void*
阅读全文
摘要:题目数学模型:给定n个正整数,现要将这n个数分成k组,且满足每组的和都相等。求最多能分多少组。这题是经典的剪枝搜索题,原题来自PKU。下面的程序虽然AC了,但是跑不动POJ中discuss中的那组BT数据。View Code 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <vector> 5 #define MAX(a,b) ((a)>(b)?(a):(b)) 6 #define N 64 7 using namespace std;
阅读全文
摘要:跟"非常可乐"那题差不多,只是多了一个打印倒水步骤。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #define N 1001 5 #define MIN(a,b) ((a)<(b)?(a):(b)) 6 using namespace std; 7 typedef struct node 8 { 9 int v[2],t,d;10 }node;11 node cur,next;12 queue<node> Q;13 n
阅读全文
摘要:题目大意:英雄打怪,英雄有n个咒语,每个咒语能对怪造成一定的伤害,且只能使用一次,咒语使用的时机不同,伤害不同,具体表现为,当怪的体力小于某个特定值m时,伤害会加倍。每条咒语描述为(a,m),表示怪的体力大于m时伤害为a,其他时间为2*a。问能不能将怪打死,若能输出最少使用的咒语数,否则输出"-1"。当怪的体力小于或等于0时即认为怪死了。分析:要求最少的次数,很容易想到使用BFS,但用DFS的关键在于状态的判重,这题可以将已经使用的咒语列表构成状态,判重时不好处理。若使用迭代加深搜索IDS则不需判重,只是时间可能要多一点。因为n最大不超过10,即最大深度为10,肯定不会超时
阅读全文
摘要:题目大意:这题跟HDOJ"非常可乐"那题很像,用状态空间搜索即可。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #define N 101 5 #define MIN(a,b) ((a)<(b)?(a):(b)) 6 using namespace std; 7 typedef struct node 8 { 9 int v[2],t;10 }node;11 node cur,next;12 queue<node> Q;
阅读全文
摘要:题目模型:给定3个无刻度容器,容器的容积均为正整数,初始状态为第一个容器装满水,其它2个空着,问是否能将第一个容器中的水平分,若能输出最少操作步数,否则输出"NO".分析:典型的状态空间搜索题,要求最少步数,可以用BFS,将3个容器中中的水量组合定义为状态,倒水操作会造成状态转移。目标状态为某两个容器中水量相等且总和为总水量。一个小的优化是当总水量为奇数时,直接输出"NO".View Code 1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4
阅读全文
摘要:题目的模型:在一个图中,给定一系列目标结点,求从起点出发经过所有目标结点的最短距离。分析:由于目标结点数目最大为7,所以可以暴力搜索过,枚举经过目标结点的排列,然后计算选择最优的。计算距离时需要用floyd预处理任意2结点之间的最短距离。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define N 31 4 #define MIN(a,b) ((a)<(b)?(a):(b)) 5 #define INF 0x7fffffff 6 int d[N][N],t[N],a[N],n,m,cnt,ans;
阅读全文
摘要:题目大意:跟01背包模型有点像,区别在于01背包对选取的物品个数没有要求,而这题给出了选的个数。N最大为20,所以可以暴力过。经测试N最大好像是21,定义成20会WAView Code 1 #include <stdio.h> 2 #define N 21 3 #define INF 0x7fffffff 4 int v[N],w[N],n,m,cnt,vmax,wmax; 5 void dfs(int k,int vsum,int wsum) 6 { 7 if(cnt==m) 8 { 9 if(wsum<=wmax && vsum>vmax) vmax
阅读全文

浙公网安备 33010602011771号