1
题意
将整数n拆分为m个数的和,输出这m个数or的最小值。
题解
要想使或值最小,那么m个二进制数中的最高位应尽量小,假如存在k使$(2^k-1)m > n > (2^{k-1}-1)*m$,所以m个二进制数中至少有一个数的最高位为k。因为是取各位取或,所以此时应让尽量多的数的第k位为1,$ans += 2^k$,从高位向低位递推,直到n变为0。
2
题意
代码
1 | //solution1 |
3
题意
设一个排列,当i为奇数,a[i]>a[i-1],求满足条件的长度为n的数量
题解
设答案是 $f(n)$
考虑最⼤大的数的位置是 i,则变成一个长度为 i-1 的数列列和一个长度为 n-i 的数列列
所以 $f(n)=\sum\frac {f(i)f(n-i-1)} n$
所以 $f(x)’=f(x)^2+1$
解得 $f(x)=tan(x)$
4
题解
n+1个数由1-n 组成,只有一个重复的,找出来。
代码
1 | int findDuplicate(vector<int>& nums) { |
5
法一: 求每个点左边连续比它大的最左边的下标,保存在l[]数组里,求每个点右边连续比它大的最右边的下标,保存在r[]数组里
法二: 维护一个单调栈, 如果h大于栈顶元素,则入栈, 否则,将栈内元素出栈,直到满足上面的条件。出栈时,我们要将出栈元素对之后问题的影响全部考虑进行处理,才能保证做法的正确性。
6
只需n+m-1个就可以填满,
当插入点(x1,y1) 时有关系x1<=>y1
当插入点(x2,y1) 时有关系 x2<=>y1<=>x1
当插入点(x1,y2) 时有关系 y2<=>x1<=>y1<=>x2
用并查集来连接
7
给你一个序列n个数组成,然后让你在里面找到m个子序列,让这m个子序列的和最大。
1 | dp[i][j]表示的是第j个数字在第i个子序列时的当前最优值。 |
8
给一个函数
1 | int f(int x,int y){ |
给出n,m,p,求$\Large\sum\limits_{i=1}^n\sum\limits_{j=1}^m\lfloor\frac {i*j} {f(i,j)}\rfloor$
9
有n家银行围成一个圈,有个人在有些银行里欠了钱,在一些银行里有存钱,欠的钱总数等于存的钱总数。现在可以有操作,如果两个银行相邻,那么就能在一个银行转任意多的钱到另一个银行。问最少的操作次数,使得在所有银行的存款钱数都为0。
首先我们要发现第一个贪心。如果有一段子串,里面的数字之和等于0,那么在这段子串中移动数字,所需要的代价为子串长度len-1,那么问题就转换成了,我们在这个圈中能找到多少段子串,里面的数字之和等于0,而且段数越多越好,记为k,那么很明显,答案就是n-k,现在问题来了,如何来求满足题意的最大的k。首先,我们考虑用前缀和来存放,如果遇到两个位置,前缀和相等,那么中间那一段数字之和肯定等于0。接下来就是一个跳跃性的思考了,那么如果某个前缀和的值出现了k次,是不是就是我们上述的k呢?答案是正确的!假如有k个位置的前缀和相等,那么中间k-1段子串内数字之和一定都是0,由于总数是0,那么最前面和最后面连着的那一段也肯定是0,所以,我们记录所有的前缀和的值,然后排序。然后用取尺法记录一个数出现的最多次数,就做完了
10
将整数n拆分为m个数的和,输出这m个数or的最小值。
要想使或值最小,那么m个二进制数中的最高位应尽量小,假如存在k使$(2^k-1)m > n > (2^{k-1}-1)*m$,所以m个二进制数中至少有一个数的最高位为k。因为是取各位取或,所以此时应让尽量多的数的第k位为1,$ans += 2^k$,从高位向低位递推,直到n变为0。
11
求a~b间素数个数(1 ≤ a ≤ b < 2^31, b - a ≤ 100000).
1 | memset(visab,0,sizeof(visab)); |
12
求和
1 | //solution1 |
13
设一个排列,当i为奇数,a[i]>a[i-1],求满足条件的长度为n的数量
设答案是 f(n)
考虑最⼤大的数的位置是 i,则变成⼀一个⻓长度为 i-1 的数列列和一个⻓长度为 n-i 的数列列
所以 f(n)=sum(f(i)f(n-i-1))/n
所以 f(x)’=f(x)^2+1
解得 f(x)=tan(x)
14
n+1个数由1-n 组成,只有一个重复的,找出来。
1 | int findDuplicate(vector<int>& nums) { |