第二场(11.20)
A、热心的牛牛
我的代码:
public long Maximumcandies (long n, long k) { if(k % (n+1) == 0){ return k/(n+1) -2; }else{ long temp = k%(n+1); long res = k/(n+1); long p = k/(n+1) + temp/n; if(res < p){ return res; }else{ return res-1; } } }
别人的代码
public long Maximumcandies (long n, long k) { return (k - n) / (n + 1); }
B、牛牛切木棒
斐波那契数列
三角形的三边定理和斐波那契数列的关系:
由于形成三角形的充要条件是任何两边的和大于第三边,所以构不成三角形的条件则为存在两边之和不超过第三边。
结合题目分析:因为要使得分出来的段数最多,所以前面符合条件的长度要尽可能小。前两段取1,然后第三段取2,然后接着后面取的段数都为全面两段的和,这样即满足了不能构成三角形的条件,也能够保证后面剩下的长度更长。
1,1,2,3,5,8 ················ 这样不就是斐波那契数列了嘛。所以最后当形成的斐波那契数列的和大于总的长度时,即返回数列的下标即为分得的段数。
public int stick (long a) { long[] f = new long[61]; f[0] = 1; f[1] = 1; for(int i = 2; i < f.length; i++){ f[i] = f[i-1] + f[i-2]; } long ans = 0; for(int i = 0; i < f.length; i++){ ans += f[i]; if(ans > a) return i; } return -1; }
C、TreeII
常规解法: 队列
解题过程:
1、先将根结点入队
2、队首出队 => now,此时now依次与它的每一个子结点进行异或并累加到返回结果res中,每一个异或操作,都得将该子结点入队
- 第一次的循环,当队列不为空的时候
- 循环结束的标志,当前结点等于最后一个结点时
- 异或操作的循环,因为为k叉树,所以每一个根节点都有k个子结点
- 最后一层没满,所以循环的条件为 当前结点小于最后一个结点
3、返回结果 res
public long tree2 (int k, int[] a) { //当前子结点下标为1 int curPos = 1; //整个数组的长度 int len = a.length; //返回的结果 long res = 0; Queue<Integer> q = new LinkedList<>(); //根结点入队 q.offer(a[0]); //循环的条件 队列不为空 while(!q.isEmpty()){ // 当前子结点到最后一个结点时,循环直接终止 if(curPos == len) break; //当前结点(队首) int now = q.poll(); //K叉树,所以需要异或K次(在当前层完全的情况下) for(int i = 1; i <= k; i++){ //当curPos<len时,才进行操作,因为当 当前子结点到最后一个结点时,那个这一层就是最后一层 if(curPos < len){ res += now ^ a[curPos]; q.offer(a[curPos]); // 该子结点入队 curPos++; // 最后curPos == len } } } return res; // 返回结果 }
解法优化:
去除队列
public long tree2 (int k, int[] a) { int curPos = 1; int len = a.length; long res = 0; for(int i = 0; i < len; i++){ if(curPos == len) break; for(int j = 1; j <= k; j++){ if(curPos < len){ res += a[i] ^ a[curPos]; curPos++; } } } return res; }