摘要:
题意:有一个国王要把他的领土分给两个儿子,国王的领土是一棵树,N个结点,N-1条边把这些结点连起来,现在大小儿子要选择一个点作为他的首都,那么除首都分别是这两个儿子之外,其他的城市(结点)根据离谁近就归谁所有,如果一样远的话就归大儿子所有,现在假设两个人都采取最优策略,且大儿子先选,问大儿子最多能够得到多少城市?解法:如果大儿子选择了一个点P,那么这个小儿子选择的点一定在P点的某个子树(M)当中,且P的其他子树一定归大儿子所有,对于子树M,小儿子的最优策略显然是选择和P相邻的哪一个点,否则将损失更多的城市。那么最后的解法就是大儿子选择一定P,改点满足P的所有的子树中拥有最大结点数的子树最小。这 阅读全文
摘要:
题意:给定一张图,现在对这张图进行染色,且相邻的两个点的颜色不能够相同,问最少要用多少种颜色?思路:有一下贪心思路,对于没一个节点,我们对其周围的结点进行遍历,对有颜色的邻节点的颜色进行统计,选取一种编号最靠前且不与周边颜色冲突的颜色对改点进行涂色。由 于我们的涂色都是按编号从小到大因此该策略下能够产生最小的颜色集合。可以简单的证明下:假设现有N个点,对部分点已经进行了涂色,且满足条件,现在问题就是我们 的算法在要添加一种新颜色的时候还在用以前的颜色,导致后面出现了更多的颜色开销(违背贪心规则,如果确实这样的话,此题则变为动态规划求解),但是我们得出的推 论是,如果一个点应该被涂... 阅读全文
摘要:
题意:给定一个数独的题目,0代表这个点的值未确定,现在要求填写数字进去且满足:1.每一行必须是1-9的集合2.每一列必须是1-9的集合3.每一个子矩阵内必须是1-9的集合由于给定的约束条件比较多,因此直接dfs即可。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;char G[15][15];int r[15][15], c[15][15], f[15][15];// G用来保留整个图,R用来说明某一 阅读全文
摘要:
题意:给定一个完全图,现在要求将这个图划分成两个部分,求两个部分的点做笛卡尔积之后的点对的距离和最大值是多少。解法一:由于给定的点最多只有20个,所以直接2^N*O(n)的时间复杂度枚举即可。解法二:采用随机化算法,枚举某一个点,将这个点所属于的集合进行翻滚。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <iostream>using namespace std;int N, G[25][25];int cal(int x) { int A[25], B[25 阅读全文
摘要:
这一题不是自己想出来的思路,看了一眼解题报告。题意是这样的,求给定的一棵树中是否存在一条长度为L的路径,注意这个值可能为负数,这也是简洁版的解题报告的最后一句忠告。这题有一个非常好的特性,那就是所有的边的长度要么为1,要么为2,也就是说我们所求得的路径是由若干个1,2组成的。那么也就有了下面的结论:当我们得到一条长度为S的路径时,现在考虑到构成路径S的左右两端的两条边,这两条边的组合情况是(1, 1), (1, 2), (2, 2)那么注意到我们始终可以去掉长度为2的一段,因此有结论:若整个树中最长的偶数边为EM,最长的奇数边为OM,由于任何一个询问不是奇数就是偶数,那么如果这个数是偶数的话, 阅读全文
摘要:
题意:给定一棵树(不一定是二叉树),现在问最多能够删除多少条边使得分开的结点满足分开子树的结点数都是偶数。思路:首先用邻接表建立起一棵树,然后我们得出以下的结论:对于任意结点而言,如果该节点能够找出和与之相连的部分子树构成偶数个点并且这偶数个点不能再分解出偶数个结点的分支出来,那么这个点与其他相连的子树(没有加入前面的集合中)的边全部断掉。之所以可以断掉这些边是因为一个我们去掉的点集都是不能够再进行分割的集合,而且又达到了偶数个点,那么这偶数个点对于其他集合肯定也是没有帮助的,因为%2之后的贡献率为0。代码如下:#include <iostream>#include <cst 阅读全文
摘要:
看了公式之后k的值来源是i或者是j,那么枚举 i = k 的时候满足(j < i)同理 j = k 的时候满足(i < j) 最后在加上i,j都是k。求一个前缀和。注意处理溢出。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <iostream>#define MOD 1000000007using namespace std;int N;long long sa[100005], sb[100005];int cal(int x) { return 阅读全文
摘要:
给定一个集合A,一个集合B,A,B元素个数相等,然后问是否存在一个数X使得A中的元素均与这个数进行按位异或操作后的结果为B集合,如果存在输出最小的数,不存在输出-1。思路:由于给定的N为奇数,所以能够根据二进制位的最右边位确定唯一的分组,然后只需要判定这个分组是否合理即可。分组是这样划分的,如有A、B两组数据,把A组根据末位0和1分成两组,B组同理划分,那么只有00配对或者是01配对,这有各组中数的个数确定。配对模式确定后,再通过30次判定即可。#include #include #include #include #include #include using namespace std;c 阅读全文
摘要:
这题让我想起了杭电的那一道三个可乐罐的题目,那一题好像只要输出次数就可以了,而这里则需要将所有的路径全部输出出来,这样的话,单纯的BFS则会在状态的保留上会出现大量的空间冗余。于是这题在考虑到搜索空间一定的情况下,并且这些空间具有只访问一次的特性,因此,可以直接对题目进行构图,也就是相当于BFS中不对队列进行删除元素。通过一个二维数组来存储传递路径,再通过一个二维数组来存储父亲结点。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <queue>#include 阅读全文
摘要:
这题大概题意是这样的,给定log2(x + y) = A 以及 log2(x - y) = B,现在要求出log2(x)是多少。首先这题中给定的A、B的范围是骗人的,实际上A、B的差值不能够大于1024,否则就不能够使用pow函数,不知道这种方法是不是错了。首先有log2(x) = Min(A, B) - 1 + log2(2^|A-B|+1)那么我们就能够估计这个值的范围是[Min(A, B) - 1 + |A-B|, Min(A, B) + |A-B|],我们对log2(2^|A-B|)这个式子进行二分求值,最后得到结果。这题的二分真是诡异,明明最后边界L和MID的差值是小于10^-8的, 阅读全文