02 2014 档案
摘要:题意是给定n个大写字母组成的字符串。选择尽量多的串,使得每个字母的出现次数为偶数。 可以把每个单词转化成01串,然后用异或操作处理。 这里如果枚举所有情况的话复杂度是2^n,白书上面介绍了一种中途相遇法,可以把复杂度降低到2^(n/2)*logn甚至更低 方法是先穷举前n/2异或的所有可能值,如果有相同的保留最大的,可以用hash或者map存储映射关系。 然后穷举后n/2的所有可能值...
阅读全文
摘要:简单的扫描算法 #include #include #include using namespace std;const int maxn = 1005;int T,M,N,mat[maxn][maxn],right[maxn][maxn],left[maxn][maxn],up[maxn][maxn];int main() { scanf("%d",&T); while(T--) { int...
阅读全文
摘要:假设有两个小孩子在跑道上面跑,如果跑道视环形的,那么速度快的那个小孩一定能追上速度慢的那个。 #include #include #include #include #include using namespace std;int next(int k,int n) { long long s = (long long)n; s = s * s; int len = log10(s) + ...
阅读全文
摘要:寻找一个序列中和不小于S的最短子序列,n的时间预处理出前缀和,然后枚举末位置二分初始位置nlogn搞定#include #include #include using namespace std;const int maxn = 100001;int A[maxn],B[maxn];int main() { int n,S; while(~scanf("%d%d",&n,&S)) { int ans = 0; for(int i = 1;i = S) { if(ans == 0) ans = i - str + 1; else ans = min(ans,i
阅读全文
摘要:LA3971 Assemble你有b块钱,给出n个配件的个子的种类,性能和价格,每种类型的配件买一个,价格不超过b,因为有水桶效应,所以电脑的性能取决于性能最低的配件的性能,问你b块钱配的电脑性能最高有多少。按照白书的说法,最大值尽量小,最小值尽量大之类的问题一般都可以用二分答案的方法来结局,这道题就是一道典型的最小值最大问题,所以采用二分答案#include #include #include #include #include #include #include #include using namespace std;const int maxn = 1005;struct Compon
阅读全文
摘要:汉诺塔问题的变形,给定初始局面和目标局面,问最少多少步可以把初始局面变成目标局面。找到初始位置和目标位置不同的最大盘子X,那么比这个盘子还大的盘子就可以无视掉了。因为他们既不会被移动也不需要被移动。我们设f(p[],x,final)为当前初始状态为p,要把比x小的盘子移动到柱子final的最少步数那么有f(p[],x,final)=f(p[],x-1,6-final-p[x])+2^(x-1)-1+1意思就是先把比x-1小的都移动到柱子6-final-p[x],然后把x-1移动到final,然后把比x-1小的盘子移动到final有了这个式子之后,我们要求的答案可以分解成,从开始局面开始,把比X
阅读全文
摘要:给定一个1….n的正整数序列,每次操作可以从序列寻找出一个或多个正整数,然后同时减去一个相同的正整数。通过画图可以发现只要把后一半都减去n/2就和前一半一样了,所以有递推式 f(n )=f(n/2) + 1#include using namespace std;int f(int n) { return n == 1 ? 1 : f(n >> 1) + 1;}int main() { int n; while(~scanf("%d",&n)) { printf("%d\n",f(n)); } return 0;}
阅读全文
摘要:给你一个n*n的矩阵,你的任务是把尽量少的0变成1,使得每个数字的上下左右元素之和是偶数。直接暴力肯定会超时,找到行与行之间的关系,可以发现只要枚举第一行的所有情况,后面行都可以算出来。#include #include #include using namespace std;const int maxn = 16;const int INF = 2100000000 / 2;int mat[maxn][maxn],ans,n;int getsum(int x,int y,int m[maxn][maxn]) { int ans = 0; if(x > 1) ans += m[x -
阅读全文
摘要:题意是一个圆桌上面做了n个人,每个人手头上有不同数目的金币(每个人手头的金币数目已知),然后他们需要通过相互交换来使得大家手头上面的金币数目相等,求最少流通值。白书上面用了一个非常强劲的代数做法,觉得这个思想还是需要学习一下的。因为人数和总的金币数是确定的,而且题目确保了一定除得进,所以最终情况下每个人手头的钱币数量是确定的,设为M,把人编号1,2,3,4,..n,设xi为编号i-1的人给编号为i的人的金币数,我们最终要求的值即为|x1|+|x2|+…+|xn|,Ai为每个人初始状况下手头的钱币数,有A1+x1-x2=M → x2=A1-M+x1 A2+x2-x3=M → x3=A2-M+x2
阅读全文
摘要:题意是原本n个墓碑均匀分布在一个周长为10000的圆周上,现在加入m个,如果要使得n+m个墓碑都均匀分布的话,那么原来的墓碑最少的移动总距离是多少。因为加入m个之后m+n个墓碑的位置是固定的,要是移动距离最少必定会有一个墓碑不动,将圆周分成m+n段,分别标上0,1,2,3,4。。然后需要移动的墓碑坐标就是数轴上面的非整数点,两边的值靠近哪个就选哪个,之后再等比例扩大即可。#include #include #include using namespace std;int main() { int n,m; while(~scanf("%d%d",&n,&m)
阅读全文

浙公网安备 33010602011771号