03 2013 档案
摘要:题意:有N个国家,每个国家属于一个洲,现在有人要来攻击一些国家,每次攻击选择来自三个不同洲的国家,我们能够选择去保护一个国家,被保护的国家恐惧值-2,其余两个国家恐惧值+2,和这两个国家在一个洲的国家恐惧值+1。分析:由于超过5点恐惧值就以及超过极限了,而每次攻击又会带来其余两个洲恐惧值的增加,因此最多在不超过10天的情况下将会出现有国家超过5点恐惧值。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <iostream>#include <algorith
阅读全文
摘要:A:小Y做家教简单的想法题。使用hash表或者是map存储所有数,然后从最小的数开始找从这个数开始的连续P倍数的个数X,那么需要删除的数的个数为X/2。代码如下:Problem AB:小Y的难题Ⅰ组合数学题,通过经典的一一对应原则推导出答案为N^(N-2)。http://wenku.baidu.com/view/2e1ab2757fd5360cba1adbba.htmlCayley定理在组合数学中的应用。代码如下:Problem B#include <iostream>#include <cmath>#include <cstring>#include &l
阅读全文
摘要:看了下面这篇文章后就恍然大悟了,不得不佩服解题方法的精妙之处。http://blog.csdn.net/wh2124335/article/details/8739097题目大意:在第一象限中给出若干矩形(点范围1e5,矩形个数20000),现在给出一些询问(次数20000),每次询问给出一个整数t,问在(0,0)到(t,t)范围的矩形面积和。解题思路:考虑每次询问t,对于单一矩形的面积的计算方法~对于询问t。计算如图矩形所被包含的面积可以用矩形面积S[TCFI]-S[TJGI],而S[TCFI]=(t-Fx)*(t-Fy);S[TJGI]=(t-Gx)*(t-Gy)换句话说就是用[T和矩形左
阅读全文
摘要:题意:破解一套1-6位长度密码的系统,寻找这样一个序列:对于N位的密码10^N+N-1长度的连续的长为N的串能够枚举完所有的密码。解法:构图之后直接dfs会超内存,因此需要使用栈来实现。调了很久。代码如下:#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;int N, mod, head[100005];int idx, lim, edge, top;int st
阅读全文
摘要:题意:给定许多根棍子,这些棍子两头有不同的颜色,问是否能够存在这样一中组合方式使得所有的棍子首尾相连。解法:这题使用map处理字符串超时了,所以自己写了一个插值取模的字符串hash。只要判定图是否连通和度为奇数是否大于2个即可,不可能出现奇数个度为奇数的点。代码如下:#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>#include <map>#include <string>#
阅读全文
摘要:题意:给定一系列的单词,这些单词要使用类似与成语接龙的方式将他们连接起来,现在问是否存在这样一个通路。解法:为什么这种题目刚看起来总是像那个什么哈密顿回路呢?欧拉回路主要解决对边的遍历问题,因此我们需要将已知条件转移到边上的信息即可。对于一个单词acm,那么就连接一条从a到m的边,那么走这条边也就访问了这个单词。有向图判定是否存在欧拉路径的方法是:在保证图连通的情况下,所有点的入度等于出度或者是存在两个点,一个点入度比出度大1,另一个点出度比入度大1。代码如下:#include <iostream>#include <cstring>#include <cstdl
阅读全文
摘要:题意:给定一个无向图的关系,判定是否存在一条从M点出发回到0点并且走遍所有边的通路,也即欧拉通路。解法:该题如果当出发点就为0点话就等效于是否存在欧拉回路了。欧拉通路的判定条件为:连通的无向图中,度为奇数节点的个数为0个或者是2个。由于该题限定了起点和端点,因此度为奇数的点只能够由两个,且为M和0。当M==0时,奇数节点个数为0个符合题意,此时将构成一条欧拉回路。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <iostream>#include <alg
阅读全文
摘要:题意:给定一个序列,求出这个序列中最长的一个对称的序列,并且该序列对称之中还要保持左边递增右边递减。解法:将原串进行翻转,然后求一个最长公共上升子序列,注意边界:从原串的第i位开始匹配,那么翻转过来的串就不能够匹配到[1,i-1]这个区间去,否则非法的这一段匹配结果将会是左降右增。代码入下:#include <cstdlib>#include <cstring>#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>using na
阅读全文
摘要:题意:有这样的一个天平,关于天平的中心两边有一些钩子,钩子有一个属性就是离中心的距离。题中给定的是设中心的坐标为0,左右两边分别是负数和正数的坐标值。现在给定一些砝码,问将这些砝码都挂到天平上,使得天平保持平衡的方式有多少种?一个钩子上可以连续挂上多个砝码。解法:首先将所有钩子的坐标都加上15,然后使得最后砝码乘以坐标的总和等于总质量乘以15。这样原问题就转化为一个类似于背包的问题了。代码如下:#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>using
阅读全文
摘要:大d的考题题意:给定一个N*N的矩阵,里面放置1,2,3...N*N这N*N个数,要求是第i个数的行和第i-1个数的列必须相同。问1所在的行的和值与N*N所在列的和值之差最小是多少。解法:通过dfs搜索得到1,2,3,4对应的解分别为0,2,6,12,当N=5的时数据规模已经庞大到无法在有限时间内得到结果了,根据这几组结果推断结果为ans = (N-1)*(N)。提交AC。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#include &
阅读全文
摘要:题意:给定一个多项式,对其进行因式分解。解法:由于多项式每一项系数绝对值不超过1000,由于最后解的形式为(x-a)(x-b)(x-c)(x-d)(x-e)其中a*b*c*d*e一定是最后的常数项系数,因此a, b, c, d, e的取值范围都在[-1000, 1000]内,因此枚举所有的根,剩下的就是重根的时候该怎么办?一个解决办法就是对原多项式进行求导,如果一个根t是f(x)的K重根的话,那么t一定是f(x)'的K-1重根。该题的字符串处理我没写好,后面调了很久。还有就是由于有5次方存在,因此代入时使用long long计算。代码如下:#include <cstdlib>
阅读全文
摘要:题意:告诉某一天,然后往前和后各推一定天数,输出计算之后的日期。解法:一天一天模拟,日期的在各个位的进制不尽相同。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;int month[13] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};bool leap(int y) { return (y%4==0 && y%100!=
阅读全文
摘要:题意:有N头牛,这些牛都拥有一个属性x表示其在坐标轴上的坐标。现在给定ML组约束条件表示A、B两头牛坐标之差不能够超过C;MD组约束条件表示A、B两头牛坐标之差不能小于C,现在问1和N号牛之间最长的距离为多大,如果存在则输出最大长度,如果任意输出-2,如果已知条件存在矛盾输出-1。解法:根据已知条件建立约束系统,问题在于形容两个点之间的距离看似是一种双向边的关系,但是如果一旦建立双向的负边那么就会发生错判了,这显然是错误的,因此我们只能够建立单向的边。为每一个点都选择一个参考点,我选择N号点作为参考点,那么每个点的相对距离就变成了与N号点的距离之差,所有边就都成为了从编号小的点指向编号大的点,
阅读全文
摘要:题意:已知A0 = 0 , A1 = 1 , An = 3 * An - 1 + An - 2 (n >= 2). 求 AAAAN Mod (1e9 + 7) (也就是A[A[A[A[N]]]])。解法:标程竟然使用set+pair来寻找循环节,并且第一次循环节长达222222224,不知道内存要吃掉多少。由于是一个嵌套的定义,因此要找出每一层的循环节,最终推出最内层的循环节为240,次之为183120,再之222222224,最后就是1e9+7了。通过矩阵快速幂求解第x项还是飞快的,注意当某一层为0时最后的结果就为0了。代码如下:#include <cstdlib>#inc
阅读全文
摘要:题意:给定N个任务,每个任务有一个完成时间。这些任务之间有完成的四种先后顺序,假设这种二元关系建立在x,y之间: SAS:x至少在y开始时开始 SAF:x至少在y完成时开始 FAS:x至少在y开始时完成 FAF:x至少在y完成时完成 现在问这些任务在最短时间内都被完成的任务安排如何?输出每个任务开始的时刻,如果不能的话输出impossible。解法:根据开始时间建图,之后再虚拟出一个任务0,这个任务必须在每个任务完成后完成,因此在0到每个任务之间添加一条边,最后计算出所有节点中到0点最迟的开始的任务,设该任务0点开始,并让每个任务的开始时间都加上这个时间差。代码如下:#in...
阅读全文
摘要:题意:问最少多少个过同一点的平面能够将空间分成N份。解法:这题的基本思路肯定是求出x个平面最多能够划分出多少个子空间,然后二分枚举出答案。小涛神说了一种非常神的方法来解这一题,那就是得到三组最简单的解,假设最后的通项公式是一个最高次为1次的表达式,那么采用待定系数法用两组数据得到表达式然后使用第三组检验前两组得出的解。如果不相符的话那么再推出一个解,假设通项公式最高次为2次解方程...最后就能够得到这题的通项公式:f(x) = x*x - x + 2。 当然,我是想使用递推公式来解决这一问题,由于三个平面最多将空间分成8份,而在增加一个平面的话,由于所有平面都要过一个点,那么三个平面就已经确.
阅读全文
摘要:题意:求出两点的距离。解法:由于有一种情况相加将超出long long的最大表示范围,由于计算机将减法都视作是加法,因此溢出之后的值如果使用无符号格式控制符来输出的话,结果是对的。代码如下:#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <algorithm>using namespace std;int main() { int T; scanf("%d", &T); while (T--)
阅读全文
摘要:题意:下图给定边长L和旋转角度a,求重叠之后的面积。解法:由于紫色的角已知是45度,加上a已知,可以推出phi等于a,设红色边长度为x,有x+x*cos(a)+x*sin(a) = L,根据公式得到x = L / (1+cos(a)+cos(a)),由于四个多出来三角形面积和形状都相同,因此重合的面积为L*L - 1/2 * x*cos(a) * x*sin(a) * 4 = L*L - x*x*sin(2*a)。代码如下:#include <iostream>#include <cstring>#include <cstdlib>#include <
阅读全文
摘要:题意:有这样的一个需求,一个程序能够动态的插入数字,并且能够以很快的速度给出一个数字在已有的数字集合中异或之后值的最大或者是最小值。解法:将插入的数构成一棵字典树,然后将每一个数字以贪心的思想去匹配,如果一个数字为1010,要求与它异或之后值的最小值,只需要在为1的地方优先匹配1,为0的地方优先匹配0;如果是求最大值就把这个数字进行取反操作,然后找出一个数与取反之后的数异或值最小即可。代码如下:#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#incl
阅读全文
摘要:题意:询问一个区间内要么只包含3,要么只包含8的数有多少个?解法:数位DP,可惜比赛的时候忘了怎么写了,随便写了个DP没有过,后来才调过了。正确解法是开设一个状态: f[i][0]表示剩下i+1位数中且暂时不含有3,8的满足要求的数的个数(i位数字可从全0取到全9,后同) f[i][1]表示剩下i+1位数中且暂时只含有3的满足要求的数的个数 f[i][2]表示剩下i+1位数中且暂时只含有8的满足要求的数的个数 f[i][3]表示剩下i+1位数中且已经含有3和8的满足要求的数的个数,该结果恒为零 标程的解法使用了位运算来计算状态,非常清爽。代码如下:#include <cst...
阅读全文
摘要:A:Non-negative Partial Sums题意:给定一个序列,我们能够给这个序列做一个循环移位的操作,即把第一个数字放到整个序列的最后一位。问存在多少种移动后的状态满足对于所有的前缀和都大于等于0。解法:对于一个长度为N的序列,设从1-i的前缀和为sum[i],假设已经有K个数字从前面移动到序列的后面,那么对于当前序列的前N-K个元素减少的值为移动到后面的K个数字的和,增加为0,因此从sum[K+1...N]从选择一个最小的减去sum[i]查看是否大于等于0即可。对于后面K个元素,增加的值为sum[N]-sum[i],减少的值为0,因此从sum[1...K]中选择一个最小的加上su
阅读全文
摘要:题意:德黑兰的一家每天24小时营业的超市,需要一批出纳员来满足它的需求。超市经理雇佣你来帮他解决一个问题————超市在每天的不同时段需要不同数目的出纳员(例如,午夜只需一小批,而下午则需要很多)来为顾客提供优质服务,他希望雇佣最少数目的纳员。超市经历已经提供一天里每一小时需要出纳员的最少数量————R(0),R(1),...,R(23)。R(0)表示从午夜到凌晨1:00所需要出纳员的最少数目;R(1)表示凌晨1:00到2:00之间需要的;等等。每一天,这些数据都是相同的。有N人申请这项工作,每个申请者i在每天24小时当中,从一个特定的时刻开始连续工作恰好8小时。定义ti(0<=ti<
阅读全文
摘要:题意:和上一题比较像,不过这里不是根据已知的约束求出另外一个约束,而是判定是否存在解。给定一个区间的和值区间,问整个区间能否满足所有的要求。解法:虚拟一个超级源点,超级源点到点i的最短路表示到第i个数时总和为dis[i],为了保证每个点能够被计算到,那么需要从超级源点连一条没有什么影响的边出来。然后对整个图求一次spfa,观察是否存在负环。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>us
阅读全文
摘要:题意:给定若干个连续的整数区间[ai, bi]以及ci,现在要求这样一个集合Z,集合Z中的元素与每个给定的区间的元素交集至少有ci个。解法:通过把dis[i]看做Z中小于等于整数i一共有多少个元素。那么对于题目给定条件有表达式dis[b] - dis[a-1] >= ci,根据这个不等式就能够进行构边了。除此之外,还有一些隐含的条件:0 <= dis[i]-dis[i-1] <= 1,对这些关系同样进行构边。然后要求的值就是dis[Max] - dis[Min-1] >= M中的M,其中Max和Min是出现的最小左、右边界,令dis[Max] = 0,那么就是求解的就是
阅读全文
摘要:A.素数矩阵题意:给定一个矩阵,每次能够给矩阵中的元素加1或者是减1,问使得矩阵的某一行或者某一列满足所有元素都为素数的最少操作是多少次(没加1或者减1视作一次操作)。解法:先把给定数字域内的素数全部筛选出来,记得稍微超过最大数,因为可能是变成一个超过最大数的素数,然后就是求出每一个数变成相邻素数的最小代价,统计出某一行或者是某一列的综合即可。代码如下:Problem A#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdli
阅读全文
摘要:题意:告诉我们一系列的不等式,当然这些不等式都是两个变量之间的差值,而非和值。刘备拥有N个军营,每个军营都有一个人数的上限,现在陆逊的探子来报刘备的[a, b]军营总人数不低过某一个值,现在问根据这些答案陆逊是否能够正确推断出刘备至少在各营一共驻扎了多少部队,如果不能推出,输出“Bad Estimations”。分析:根据给定的条件,我们设sum[i]表示刘备前i个军营一共驻扎了多少人,那么每个军营至多有多少人就能够通过不等式列出来。假设一共有三个军营,上限分别为A,B,C,那么有:0 <= sum[1] - sum[0] <= A0 <= sum[2] - sum[1] &
阅读全文
摘要:D.求体积题意:给定一个从中间挖去了一个圆柱(上下面是球的弧面)的球,告诉了剩下圆柱的高(可以看做是球剩下的高度),求球的体积是多少。解法:由于只给定了高度,所以存在不同半径的球都能够达到这个高度的要求,所以假设一个极端情况,那就是球的直径刚好等于已知的H,那么中间的圆柱就不用挖去了,所以剩下的就是球的体积。可惜还是不能够证明出为什么会这样。代码如下:Problem D#include <cstdlib>#include <iostream>#include <cmath>#include <iostream>#include <cstdi
阅读全文
摘要:题意:给定一个图,求出两点之间的最短路,但是这个最短路是在一条路径上的某条最贵的边能够忽略的情况下的最小值。分析:直接求出一条最短路再减去这条最短路中的最大值的做法是错误的。例如:如果A-B存在一条(2, 2, 2, 2, 2)的总长为10的路,减去最大值之后是8,存在另外一条路径(1, 8, 2),总长为11,但是减去最大的8之后就是3了,因此这里要用到动态规划来解。设dp[0][i][j]表示从i到j不使用免费权的最短路径,dp[1][i][j]表示使用免费权的最短路径,则有动态方程:dp[1][i][j] = min(dp[0][i][k] + dp[1][k][j], dp[1][i]
阅读全文
摘要:题意:给定一个网络,每条线路都同时有几个公式拥有,现在问某两点之间哪些公司通过自己拥有的路径单独联通。分析:问题开起来是给定了多个图,对他们分别求一个连通性,但是这里把多个图压缩到一个int型数字内,因为这里只是简简单单求一个连通性,使用位运算非常高效。代码如下:#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>using namespace std;int G[205][205];int N;void floyd() { for (int k = 1;
阅读全文
摘要:题意:从若干个S点出发到达T点,稍有不同的是,要区分该点落脚有左脚和右脚两种情况。解法:从题目中给定的S出发,左脚和右脚都可以踏上去,全部入队列后再spfa即可。做了这题发现使用spfa来处理多源点时连超级源点都不用建立了。代码如下:#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>using namespace std;const int INF = 0x3f3f3f3f;int N, M, dis[2][6
阅读全文
摘要:题意:给定同一个图上的两种路径,求出从某点出发到另一点的路径长度来回长度之比最大的情况。该题对两套图的处理让代码十分恶心,而且最后还要输出路径。计算出最优值最后在计算一次路径,幸好没有要求在相同的情况下按照字典序最小输出。代码如下:#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <queue>using namespace std;const int INF = 0x3f3f3f3f;int N, M, K;struct
阅读全文
摘要:题意:点与点之间有多条路,并且路是按时开放的,因此需要在边上记录更多的信息。读取一行数时不知道有stringstream类。代码如下:#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <queue>#include <string>using namespace std;const int INF = 0x3f3f3f3f;int N, M, S, T;string str;struct Edge { int v
阅读全文
摘要:题意:简单点说就是给定一棵树,每个节点都有一个权值,现在要求求出这棵树的一个联通的一枝使其权值最大。解法:设sum[i]为包含i节点在内的一枝的最大权值和,那么sum[i] = val[i] + max(0, sum[j])其中(i,j)之间存在边。当sum[j]为负数时,对父亲节点的贡献就为0了。代码如下:#include <cstdio>#include <iostream>#include <cstring>#include <cstdlib>#include <algorithm>using namespace std;int
阅读全文
摘要:第十章对象和类爬山涉水终于来到了类的面前,该章开始,终于将于类进行零距离接触了。OOP设计者的思考方式采用过程性编程方法时,首先考虑要遵循的步骤,然后考虑如何表示这些数据。OOP程序员首先考虑数据——不仅要考虑如何表示这些数据,还要考虑如何使用数据。用户与数据交互的方式有三种:初始化、更新和报告——这就是用户接口。在C++中,用户定义类型指的是实现抽象接口的类设计,一个好的接口设计应该与具体的数据关系不大,使用者无需考虑内部数据时如何运转的,修改一个类也不要去改动接口,只需要去修改实现的细节。成员变量、函数类不同于C语言中的结构体,类中还定义了类中数据与程序员交互的操作,成员变量和函数的作用域
阅读全文
摘要:这题难就难再要字典序输出,要是单单floyd的话,无法保证最后得到的路径字典序最小,一个简单的反例就是如果6 5 7 8 9和6 8 1 2 9以及6 10 1 2 9同时是6-9的最短路的话,如果忽略相等情况下的更新,6 8之间是不会被7作为中间节点而更新的,但是不忽略的话,又可能被中间比较大的节点更新了。所以直接floyd(采用path[i][j] = k表示i到j通过k点的方式还原路径)是不满足题意的。因此这里采用另外一种记录路径的方式,path[i][j]表示从i到j的第二个元素编号,那么由于仅仅只记录了第二个元素,因此当距离相等的时候,我们就只需要考虑新的“第二个元素”是否更优。这样
阅读全文
摘要:题意:在一个矩形平面内,有若干道墙,现求从左部某一点到右部某一点的最短路径。解法:有一个事实是线路一定是从门两边的点上通过的,不可能出现从中间穿过的可能。因此我们就枚举两两点之间是否可达,这里就要使用到线段相交的判定。构好图之后就是一个spfa搞定。代码如下:#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>using namespace std;int N;struct Wall { double x,
阅读全文
摘要:题意:求一个点到所有点的最短距离之和加上所有点到这个点距离之和,边为单向边。解法:先做一次spfa,然后将所有的边反序做一次spfa即可。代码如下:#include <iostream>#include <cstring>#include <queue>#include <vector>#include <cstdio>using namespace std;const int MaxN = 1000005;int P, Q, idx, gdis[MaxN], cdis[MaxN];int head[MaxN], rhead[MaxN
阅读全文
摘要:题意:给定N个点求1-N的最短路,所加的附加条件就是这N个点前A个点为村庄,后B个点为城堡。马里奥用一双靴子,能够在一定距离(L)内花0时间进行穿梭,且只有K次机会,在这种情况下,求解一个最短路。分析:首先对于如何花费这K次机会是一个动态规划的问题,因此我们需要计算出哪些边允许我们进行无代价的穿梭,由于题目还给定了穿梭只能够从某一点开始/结束,因此必须保证某一路径总长度少于L并且题目中还有一个约束条件要求该路径中间不应该有城堡,因为城堡中有陷阱不能够在穿梭的途中有陷阱。而floyd算法能够很好的就算出哪些路径能够穿梭。解法:首先通过floyd算法从1开始枚举中间点,那么由于前A个节点时村庄,路
阅读全文
摘要:该题又是一个牵涉到节点之间关系通过乘法建立的关系,通过求对数将关系由乘法变为加法应该是可以的。可惜无法无法AC。改为直接相乘却过了。AC代码:#include <iostream>#include <cmath>#include <cstdlib> #include <cstdio>#include <algorithm> #include <cstring>#include <queue>#include <iomanip>using namespace std;/* 一个网络的运送问题,简化之后
阅读全文
摘要:题意:给定一个规则问龟兔赛跑的结果,问题在于乌龟在何时选择充电。解法:由于最多的只有100个充电站,而影响结果的决策发生在各个充电站,因此只要考虑到达充电站时需要采取的策略。通过一个值保留到达某站并充电的最优值即可。代码如下:#include <iostream>#include <algorithm>using namespace std;// 如果两个节点连边,那么弧头上的点一定要加油class Rule {public: static int N; // 充电站的数目 static int vr, vt1, vt2; // 三个速度值 stat...
阅读全文
摘要:题意:给定1,2,3...N个数的集合,现在求所有非空子集(相同元素不同位置视为不同)按字典序排序后的第M个集合是什么?思路:设i个不同元素组成的非空字典序子集为kind[i],通过递推关系计算出kind[i] = i * (kind[i] + 1)可从计算式上推倒。得到这个关系后就可以通过一位一位的枚举得到答案了。代码如下:#include <iostream>#include <cstring>using namespace std;int seq[25], idx;long long kind[25];int vis[25];void deal(int N, lo
阅读全文