随笔分类 - 其他
摘要:这题给定一个系列的石头,求去除一些石头后,相邻两个石头的距离最小值最大。一个判定的贪心规则就是当枚举长度为D的时候,那么我们查看[0, 1]的距离是否大于D,如果小于的话,那么就直接删除掉1号点,再判定[0,2]是否满足,如果[0,2]满足了的话,那么就把2作为起点继续即可。代码如下:#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <
阅读全文
摘要:给定两个数,这两个数的长度都不超过6位数,然后求后一个数被怎样的分割能使得其和值最接近前一个数,其实这个问题就相当于在后一个数中进行插板而已。通过状态压缩来枚举隔板即可。代码如下:#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <map>#include <queue>#
阅读全文
摘要:哈夫曼树,一个很耳熟的数据结构课上的内容。是用来处理编码的,准确的说是能够去压缩编码,本身是一种无损的压缩凡是,就是对于给定的字符做一个统计,然后根据统计构建一个长短不一的映射表,再根据这个映射表来恢复出原来的内容。这题是有一个长度为固定值得篱笆L,现在要N块木板来维护好这个篱笆,只要用锯子锯N-1次,题目就是给定N个长度,问如何安排使得最终的花费最短。花费是这样算的,要去锯那一段,那么花费就是这一段的长度。所以就有当某一段没有被分离出来时,那么它将连续作用于切割这一段的效果。因此我们希望起到这个连续作用的值越小越好,因此就可以用哈夫曼树来优化了。使用优先队列来写是非常方便的。代码如下:#in
阅读全文
摘要:这是一道面试题,可以说是数据结构中的基础题了,由先序遍历以及中序遍历生成一棵树,然后输出后序遍历。一个递归函数传递5个参数,顶点编号,先序左右区间,中序左右区间,每次进行区间长度判定,当只有一个元素就进行元素判定,递归构树。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#define MAXN 1005using namespace std;int N, p[MAXN], m[MAXN],
阅读全文
摘要:这题就是求一个矩阵中的最小面积矩阵,使得其和大于一个给定的K,由于是求最优解,所以很自然的想到了二分查找这个值,但是这题我却在不去顶是否满足二分性质的前提下匆忙的选择了二分查找,最终导致了错误。原因在与当一个面积为一个最优解的时候,面积大于该最优解的子矩阵不一定包含这个最优矩阵,例如一个5*5的矩阵的,如果最优矩阵是一个2*2的矩阵,那么1*5的面积为5的矩阵式不会包含这个2*2的矩阵的,所以......代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorit
阅读全文
摘要:听说有了打表算法算法之后,就觉得按位DP太他妈蛋疼了。直接把整个数据规模划分成10000为段的数据进行离线打表。然后再对多余的部分进行暴力就可以了。打表代码:#include <cstdlib>#include <cstring>#include <cstdio>using namespace std;int fun(int x){ if (x == 0) return 0; else return fun(x/10) + x % 10; }bool Ac(int x){ int t = fun(x); if (x % t == 0) return true
阅读全文
摘要:不管你是怎么做的,反正我是用二分做的,相当于做了一个预处理。一个最优的序列一定是 1 2 3 .. N .. 3 2 1,或者是 1 2 3 .. N N .. 3 2 1.代码如下:#include <cstdlib>#include <cstdio>using namespace std;long long rec[131100], a, b;void pre(){ rec[1] = 1; long long LIM = 1LL << 32, base = 1; int i; for (i = 2; rec[i-1] <= LIM; ++i) {
阅读全文
摘要:这题就是考察了一个单调队列,做的时候要注意由于首尾相连,所以我们就扩出一倍的空间来简化这个过程。定义f[j]表示在第j号位置结束的连续长度不超过k的最大和,那么f[j] = MAX( sum[j] - sum[k] ),其中就要求满足区间要求,由于每个点都是从前面的sum[k]得来的,所以就可以用一个单调队列来进行同步更新。详见代码:#include <cstdlib>#include <cstring>#include <cstdio>#define INF 0x3fffffff#define MAXN 100005using namespace std;
阅读全文
摘要:这题是给定了一个长度为N的串,问一个固定区域内的最小值和最大值,这题没办法通过DP来求解,因为单纯保留最值的信息是行不通。详见代码:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#define MAXN 1000005using namespace std;int N, M, seq[MAXN], que[MAXN], front, tail;/* 此题就是要求出给定序列的某一段区间内的最小值和最大值 一个长为N的序列,每次选取M长的区间进行滑动
阅读全文
摘要:这题一开始想用状态压缩DP解,后来发现状态开不下...还是没有很好的理解啊。这里将棋盘看做是两个正方形,由于只能够走对角线,所以两个正方形可以看做是无关的,因此我们只要求出每个正方形走相应步数的方案。对于k不而言,在两个正方形里面就有(1, k-1), (2, k-2)...例如这样的分法,必须保证所有的分法都是合法的。现在问题就在于如何去求一个N*N的矩阵能放置一些棋子,这些棋子要求上下左右不能够在同行同列的方案数。其实就是一个简单的递推而已,我们定义dp[i][j]表示到第i行放置j个方案数,那么dp[i][j] = dp[i-1][j] + dp[i-1][j-1]*(n-j+1),其实
阅读全文
摘要:首先将没有特殊点的所有的情况都计算出来,再将给定的点都计算到左上角的标记点,最后查看有多少个点已经被覆盖了,减去该部分,最后用快速幂输出结果,注意这里要用long long。代码如下:#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cmath>#include<queue>#include<set>#include<map>#include<cstring>#include<
阅读全文
摘要:简单矩阵...代码如下:#include <cstring>#include <cstdio>#include <cstdlib>#include <iostream>using namespace std;unsigned int temp[5][5] = { {0, 0, 0, 0, 0}, {0, 2, 3, 1, 1}, {0, 1, 2, 3, 1}, {0, 1, 1, 2, 3}, {0, 3, 1, 1, 2}};unsigned int fix(unsigned int x){ if (x > 0xff) { x ^= 0
阅读全文
摘要:这题只需要预处理两个数组就可以了,那就是一个保留从1到N,这个N个数字连在一起的长度,以及另外一个数组表示重复打印112123...123..N的这样一个打印到N的串的长度。接下来进行两次二分查找便可得到答案了。代码如下:#include <cstring>#include <cstdlib>#include <cstdio>#define MAXN 32000using namespace std;typedef long long int Int64;Int64 N, c[MAXN+5], s[MAXN+5];inline int Len(int x){
阅读全文
摘要:http://acm.timus.ru/problem.aspx?space=1&num=1057其实这题可以算是一个组合数的题目了,主要是将基于其他进制转化为基于2进制的算法,对于某一位不为1的话,那么取其他位的话是一定不满足题意的,所以要找到一个数的最高位大于1,将这一位以及后面的每一位都赋值为1,然后就是一个按位DP的过程了,dp[len][statu]表示长度剩余量为len,要求1的个数为statu个时,并且对后面的位没有要求的情况下,所有可能的解。代码如下:#include <cstring>#include <cstdio>#include <
阅读全文
摘要:这题一开始便想着DP求解,但是细想一下是不对的,因为这种位操作在没有到最后一次计算时是无法得到最优解的,也即不存在最优子结构。首先当 a 与 b 做运算时,我们分析64位上的每一位,我们知道 & 和 ^ 操作总是有一个可以产生0的,那么对于两个64的数而言我们总可以至少使得其32位等于0,再将这个数x与c做运算的话,我们就直接把x & c,那些已经为0的位一定会还是0,其余的位不是0就是1,如果结果中 1比0多,那么我们对c取反,反正就是至少会有一半变成0,以此下去超过6个数,那么这个数就一定就是0了。对于小于0的情况,我们就直接暴力。代码如下:#include <cst
阅读全文
摘要:这题可以用二分枚举答案来求解,每次枚举一个答案时我们总是选取满足要求的每个零件的价格最小者,如果金钱能够满足的话就枚举一个更大的质量,这里最好将质量离散化,这样就能枚举每个点都用相应的品质对应。代码如下:#include <cstring>#include <cstdio>#include <cstdlib>#include <algorithm>#include <map>using namespace std;map<int,int>mp;int fee[1005];struct Node{ char name[25]
阅读全文
摘要:该题题意是要求给定a,b区间内有多少个数满足二进制表示法内0的数目多余1的数目。详见代码:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int c[40][40];void pre(){ c[0][0] = 1; for (int i = 1; i <= 30; ++i) { c[0][i] = 1; for (int j = 1; j <= 30; ++j) { c[j][i] = c[j][.
阅读全文
摘要:这题打表找下规律就可以了,定义一个变量来表示增量,那么这个变量的格律就是 add = (add± 1) * 2手写了大数的类,幸好只有-1这个值,这个类是没定义减法运算的。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;typedef long long int Int64;Int64 rec[65];int N;struct BigInteger
阅读全文
摘要:Description某校数据结构课程设计期末考核即将来临。为了考查学生对树结构的认识,同时也检验学生的编程能力,该校将考核的一项内容定为:要求编写程序按编号顺序打印出节点个数不少于m的所有二叉树。编号规则:·仅有一个节点的树编号为1。·当满足以下条件之一时,定义二叉树a的编号比b大:1.a的节点数比b多。2.若a的节点数与b相等,且a的左子树编号比b的左子树大。3.a的节点数和左子树编号都和b相等,且a的右子树编号比b的右子树大。二叉树的节点用大写X表示,例如:当然当m较大时,检验答案对错的工作也是很繁重的,所以教师只打算对其中的若干个编号的二叉树进行抽查,请编制一个程序
阅读全文
摘要:先二分找到这个非平方数,然后对一个一个区间进行求和的预处理。要注意边界问题。代码如下:#include <cstdlib>#include <cstdio>#include <cmath>#include <algorithm>using namespace std;typedef long long Int;Int N, num;long long int sum[1000005];Int bsearch(Int l, Int r) { Int mid, left; while (l <= r) { mid = (l + r) >&
阅读全文


浙公网安备 33010602011771号