ACM课程设计课 Advance_Contest_1 解题报告 Apare_xzc
ACM课程设计课Advance_Contest_1 解题报告
xzc 2019/3/5 21:34
这是赵尔敦老师ACM课程设计第一节课给ACM队员挂的题,不得不说难度还是有的,一共有四道题
A. K-th Number(poj-2104) 查询区间第K大,主席树模板题
B. Super Mario (HDU-4417) 线段树+离线处理(维护区间和,单点更新,区间查询)
C. Bipartite Numbers (UVA-1051) 构造+打表+找规律+取模+素数(我认为)
D. Bipartite Numbers(UVA-1052) dfs
A. K-th Number
题意:
这道题poj 2104是主席树的入门题(模板题),求静态区间第K大,n个数,m个询问,每个询问查询数组a中区间[x,y]的第K小的数字是多少
分析:
我对主席树的理解:
- 主席树是n棵线段树,第i棵线段树记录的是a[1]到a[i]的信息
- 先把数组a[n]进行离散化处理,把a[i]替换为i在数组排序去重后的位置(是第几大)
- 第x棵线段树记录的是a[1]到a[x]这个原数组的前缀的信息
- 每一颗线段树有很多区间[L,R],第x课树的区间[L,R]记录的是从a[1]到a[x]这个范围内出现的数组的第L,第L+1…第R大的数的个数
- 所以主席树就有了前缀和的性质
- 由于相邻的两个前缀只有1个数不同,所以可以共用树的节点,相同的部分直接把左子树的指针指向原来的节点即可
贴一个我的代码 (我把网上的板子用我喜欢的写法改了一下)
今天上算法课又写了一遍
其实区间的left和right不需要维护,只要查询的时候函数传参传入即可3月15号又写一遍
附:前会长Y_Cl和卿爷的板子(指针写法,开了内存池)
B. Super Mario
没啥想说的,线段树+离线处理
- 对查询按跳跃的高度h排序
- 对所有点的高度排序
- for(所有查询)把小于该查询的点都插入到线段树中,单点更新区间和
- 查询区间和即可
C. Bipartite Numbers
题意:
多组输入,每次输入一个正整数x,(x<=99999)
要找一个x的倍数(大于x),满足这样的形式: 33333444
前面有m个连续的s(s不为0),后面是n个连续的t,这个数要是x的倍数,求满足条件的最小的数 输入对应的m,s,n,t
分析:
这个题答案的数字可能会很大
打表过后把1到99999所有的输入跑一遍要30分钟左右…
我发现m最大可以为9966,n最大为156
- 这道题我本来想的是把答案都处理出来,然后O(1)查询
- 但是我发现900位的数都不行,1000(9976)位才行,没法打表
- 我用python把1到1000个1这1000个大数分解质因数,打表跑了一晚上(只需要用99999以内的素数筛就可以了,大的素数没必要)
python打表代码(分解大数的质因数) - 我的做法是暴力4个for:
#伪代码:
for x in range(1,10):
for y in range(0,10):
if x==y:
continue
for m in range(1,10000):
for n in range(1,156): #打表打出来的
if x*11111...11%k == y*11...1%k
ans = min(ans,...)
break .......
我发现循环次数多的都是大质数*10看这个打的表, 那么能不能把这些特判掉呢?
让我来给你分析分析:
- 如果一个数是质数*10,那么它的倍数一定是以0结尾的,则t = 0
- 那么这个质数一定是sssss…ss = s*11111…11的因数
- 有因为他是个质数,那么s肯定和这个质数互质,那么必须满足:1111…1是这个质数的倍数
- 那么问题转化为:最少几个连续的1是一个给定质数的倍数? 附一个9999以内质数表
- 我们可以用秦九韶取模计算:
int solve(int N)
{
int x = 1, cnt = 1;
while(x)
++cnt, x = (x*10+1)%N;
return cnt;
}
我发现答案有的是N-2,有的是N-1,有的是N/2…一下子也没看出来什么统一的规律,没法O(1)得出结果(希望读者发现了规律的话和我交流一下),所以就跑一遍这个函数也挺快,总比4个for,N * 200 * 9 * 9快多了
D. Bit Compressor
题意:
压缩二进制信息,把n个连续的1替换成n的二进制形式,如果这样可以缩短二进制串的长度就替换(n>2)
现在给一个压缩后的串,给出原串的长度和原串中1的个数,为是否能还原原串,结果是否唯一?
思路:
dfs,不想多说了,我好困,可能以后会补充吧
具体见代码叭
我代码的可读性还是很好的
附: 福利哦
我自己写的样例生成器
把原始的01串正向压缩
我又写了对拍程序