记录SGU 刷题。
100. A+B
101. Domino
题意:经典的骨牌拼接问题,将数字看做点,骨牌看作边,转化成无向图求欧拉路。
102. Coprimes
题意:求euler phi函数。
105. Div 3
题意:给你一个数列 1, 12, 123, ..., 123456789, 12345678910, ....。问你前n(n < 2^31) 项中有多少个数可以被3整除。
观察:打个表,或者推一下就会发现规律。
107. 987654321 problem
题意:给你一个n(n <= 1e6),问你有多少n位数的平方以987654321结尾。
观察:以987654321结尾,即模1e9得到987654321,所以满足条件的数,最小的9位会有一些限制,其他较高位可以随意组合。首先暴力算出n=9时,答案是8,n小于9时答案是0。然后考虑n>9的情况,最高的n-9位有10^(n-9)-10^(n-10) = 9*10^(n-10)种选法,最低的9位有8种选法,所以答案是72*10^(n-10)。
方法:分情况讨论,暴力输出即可。
108. Self-numbers 2
题意:对于一个正整数n,d(n) = n + sum of digits of n。我们称n是d(n)的一个generator。如果一个数n没有generator,就称n是一个self-number。下面给你一个n(n <= 1e7)和k(k <= 5e3) 个询问s[1-k],让你先输出1-n中有多少个self-number,然后再输出第s[i]个self number是啥。时限500ms,内存限制4096 KB
观察:
时限很紧,可以做一个计算d(n)的优化。令sum(i) 为 i中各数位之和,d(i) = i + sum(i)。我们可以用一个静态数组sum[10000]记录下[0, 9999]的sum(i),对于[1, 1e7] 中任意的i,sum(i) = sum[i/10000] + sum[i%10000]。sum[]数组可以暴力计算,也可以利用sum[i] = sum[i/10]+i%10。
其次内存比较小。如果内存很大,我们可以用一个vis[1e7]来记录每个数是否有generator,从1到n扫一遍,每次如果vis[i] == false, 更新答案;然后vis[d(i)] = true就好了。我们注意到,在[1, 1e7]中,sum(i) <= 9*7 = 63。也就是 d(i) <= i+63。所以可以利用一个长度为64的滚动数组来实现vis[1e7]的功能。
WA:没有注意内存和时限。其次就是没有注意到询问是无序的,并且有重复。
112. a^b-b^a
题意:给你a,b,均不超过100,让你输出a^b-b^a。
方法:大整数即可
113. Nearly Prime numbers
题意:如果一个数可以表示成两个素数相乘的形式,那么就说他是nearly prime。给你多组询问,每次让你输出一个n是不是nearly prime,n <= 1e9。
方法:计算一个数的质因子个数即可,重复质因子算多个。
114. Telecasting Station
题意:数轴上若干个位置,每个位置上有些人。让你找出一个位置,使得各个位置的人数乘上各个位置到该位置的距离 的和 最小。
方法:把选中的位置作为变量,每一个有人的位置对答案的贡献是一个绝对值函数,且权都为正,所以加在一起,肯定是先递减,再递增。找一下中间位置就好了。本质好像就是一个带权取中位数。
回顾:自己是搞出导数,每个点的值都算了一下。看到别人写的比较好。对人数求一个前缀和,找到人数刚好过半的位置,就是答案。
116. Index of super-prime
题意:考虑素数从小到大排p1, p2, p3, ... 如果pi的下标i也是素数,我们就称pi是super prime。下面给你一个正整数n,不超过1e4,问你是否可以用最少数量的super prime将n分解,如果不可以输出0,如果可以,输出最小数量和方案,方案中super prime按照非递增顺序。
方法:记忆话搜索即可。因为要非递增顺序输出方案,注意更新答案的顺序或者时机。
117. Counting
题意:给你正整数n,m,k,和一个长度为n的正整数序列a[1-n],所有数均不超过10001。下面让你统计有多少i,满足a[i]^m % k == 0。
方法:将k素因子分解,对于一个a[i],用k的每一个素因子去检查a[i]即可。
回顾:自己好菜,看到大家的方法是模k的快速幂。
123. The sum
题意:让你求fibonacci的前k(k <= 40)的和。
方法:暴力求就好了。k更大的时候可能需要快速幂。
126. Boxes