网易二轮笔试的前两题:
<i> 打印大风车:
先按规律打上半部分,上半部分分左右两个部分打;
第n行直接全打印 *;
然后下半部分将上半部分中心对称过来
ps. 网易第一轮的打印图案是个大傻0,按规律处理左上部分,然后纵向横向分别轴对称一次即可
AC代码:
<ii> 小红的数组:
题意:给定长度为n(1e5)的序列 a[1] ~ a[n](1e9),以及 p(1e9)和 x(1e5),要求将序列中任意一个数修改为不大于p的正整数(选的不大于p的这个数不得等于原来这个位置的数),使得新序列的和是x的倍数,问有多少修改方案
思路:暴力枚举p肯定TLE,所以想办法O(n)处理。
(1) 因为要把某个数 a[i] 换成 pp ∈ (0,p],即相当于删掉当前a[i]再添加新数pp,所以我们先用类似前后缀和的思想,将每个 a[i] 对应出 sum_tmp[i] = sum - a[i] (全体和减去当前a[i])。
(2) 然后我们要找sum_tmp[i]需要加上最小的pp是多少 (pp > 0,所以即使本身就是x的倍数,也得处理),以达到x的倍数,那么最小的pp应该是x - (sum_tmp[i] % x),即当前sum_tmp[i]先对x取余mod = sum_tmp[i] % x,再看这个余数mod距离x有多远,即为最小的pp (此时就算sum_tmp[i]正好是x的倍数,也能处理出一个非0的pp)
(3) 得到每个位置 i 对应的pp后,首先看pp的初值是否小于p,如果小于就以x为增幅不断扩大pp,直到pp能达到不大于p的最大值。
--> 然后我们先每次进行一次ans++,意思是先把每个位置的pp的初值都累加进ans;然后记 last = (p - pp) / x,即为pp从最小的初值开始还能增长几个x在p以内达到最大,然后每次ans += last;
--> 接下来就要考虑一个很关键的问题,怎么去重? 因为完全有可能在pp不断以x为增幅扩大时会达到该位置原来的a[i]。我们将待处理的问题转化为是否存在以增幅为x扩大k次,使得pp + kx == a[i],移项得到 a[i] - pp = kx,那么我们知道pp在p以内最多扩大last次,所以在 k <= last 的基础上看是否有 (a[i] - pp) % x == 0,从而实现去重!!!
极大概率能AC的代码: