三、负数幂

负数的计算:(a + b i)(c + d i) = (ac - bd) + (bc + ad) i
然后计算就行了,不适用Cxx的形式,直接一次次乘就可以实现
其中使用大数,long无法储存
import java.io.*;import java.math.BigInteger;public class Main {public static void main(String[] args) throws FileNotFoundException {PrintStream ps=new PrintStream(new FileOutputStream("work.txt"));System.setOut(ps); //文件输出int n=123456;BigInteger a=new BigInteger("2");BigInteger b=new BigInteger("3");BigInteger a1=new BigInteger("2");BigInteger b1=new BigInteger("3");for(int i=1;i<n;i++) {BigInteger ta=a;a=a.multiply(a1).subtract(b.multiply(b1));//a=a*a1-b*b1;b=ta.multiply(b1).add(b.multiply(a1));//b=a*b1+b*a1}System.out.println(a+(b.compareTo(BigInteger.ZERO)>0?"+":"-")+b+"i");}}
四、测试次数
类比于摔鸡蛋。
此处先写摔鸡蛋的例题问题。
https://blog.csdn.net/wolinxuebin/article/details/47057707
注意,此处是和二分查找不一样的。由于鸡蛋碎了就没了,所以不能二分
问题是100层楼2个鸡蛋
因此,我们先假设egg在x层要进行一个摔
如果没碎,就在 x+(x-1)层摔
如果碎了,在1到 x-1层中间遍历摔
(以上的情况是为了保证,对于任意的一个x,能保证一个大致的平衡(即左右都为需要有x-1个测试的)
最后得出一个公式 x + x-1 + x-2 + … + 1,当这个式子大于所要求的楼层总数时,才能解出。
所以求出x = 14(是进一法求)
第二个问题就是100层楼多个鸡蛋
设n个鸡蛋吧,那么用动态规划
理由同上。dp[鸡蛋个数+1][楼层数+1]
dp[m][n] = 1+ max(dp[m][n-k] , dp[m-1][n-1]) 其中k属于1到n-1,迭代遍历
前者是如果在n层没摔碎的话,就继续测试 n + n-1。我们前面为了保证平衡,左右次数其实是相同的,因此取1到 n-k,k次遍历
后者是如果摔碎了,就直接用n-1个鸡蛋的第n-1层楼的数据+1,(+1是因为已经摔碎了
(这里直接看代码更清楚
public class Eggs{public int countMinSetp(int egg,int num){if(egg < 1 || num < 1) return 0;int[][] f = new int[egg+1][num+1];//代表egg个鸡蛋,从num楼层冷下来所需的最小的次数for(int i=1;i<=egg; i++){for(int j=1; j<=num; j++)f[i][j] = j;//初始化,最坏的步数}for(int n=2; n<=egg; n++){for(int m=1; m<=num; m++){for(int k=1; k<m; k++){//这里的DP的递推公式为f[n][m] = 1+max(f[n-1][k-1],f[n][m-k]) k属于[1,m-1]//从1-m层中随机抽出来一层k//如果第一个鸡蛋在k层碎了,那么我们将测试1~k-1层,就可以找出来,也即1+f[1][k-1]//如果第一个鸡蛋在k层没有碎,那么我们将测试k+1~m也即m-k层,// 这里也是重点!!!!// 现在我们手里有2个鸡蛋,要测试m-k层,那么我想问,//此时和你手里有2个鸡蛋要测试1~m-k层有什么区别?// 没有区别!是的在已知k层不碎的情况下,测试k+1~m层的方法和测试1~m-k没区别,//所以可以写成 1+f[n][m-k] 其中1表示为 在k层的那一次测试f[n][m] = Math.min(f[n][m],1+Math.max(f[n-1][k-1],f[n][m-k]));//这里前面是min的理由是要将结果最优//max是要保证一定能测出来}}}return f[egg][num];}public static void main(String[] args) {Eggs e = new Eggs();System.out.println(e.countMinSetp(2,100));}}
其中,Math.max(f[n-1][k-1],f[n][m-k]),max的原因是就是有可能破碎也有可能不碎,为了保证能够测出来,必须要取最大的。
那么现在再看手机问题,其实本质是一样的,其中只要设置n = 3 ,层数 = 1000即可
六、递增三元组

算法思路:先把三个数组都排序(可以调用库函数),然后只遍历b数组,由于b数组最特殊。
b数组最为特别,因为一个数组要比它小,C数组要比它大
那么总和就是每个b中的元素在a数组中小于这个元素的*在c数组中大于b数组这个元素的个数
import java.util.Arrays;import java.util.Comparator;import java.util.Scanner;public class T6 {public static void main(String[] args) {//首先是输入Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] a = new int[n];Integer[] b = new Integer[n];Integer[] c = new Integer[n];for (int i = 0; i < n; i++) {a[i] = sc.nextInt();}for (int i = 0; i < n; i++) {b[i] = sc.nextInt();}for (int i = 0; i < n; i++) {c[i] = sc.nextInt();}//对b进行遍历Arrays.sort(a);//默认从小到大Arrays.sort(b, new cmp());Arrays.sort(c, new cmp());int ans = 0;//要求是a<b<cfor (int i = 0; i < n; i++) {//如果a>b,就不比较了,直接跳出,此时j的数就是符合的数。int j = 0;for (j = 0; j < n; j++) {if (a[j] >= b[i]) {break;}}int k = 0;for (k = 0; k < n; k++) {if (c[k] <= b[i]) {break;}}ans += j * k;}System.out.println(ans);}}class cmp implements Comparator<Integer> {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1;}}
七、螺旋折线


两种解法:
第一种:https://blog.csdn.net/qq799028706/article/details/84312062
巧算
第二种自己算的:
public class T7 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int x = sc.nextInt();int y = sc.nextInt();int n = Math.max(Math.abs(x), Math.abs(y));//最大值//直接算就行了int ans = (2 * n - 1) * (2 * n - 2);//就是是x轴较大if (n == Math.abs(x)) {//右边的竖线if (x > 0) {ans = ans + 2 * (2 * n - 1) + 2 * n + n - y;}else//左边的竖线ans = ans+ 2 * n - 1 + y+(n-1);}else {//是y轴比较大,算横坐标//上面横线if (y >0){ans = ans + 2 * (2 * n - 1) + x+n;}else//下面横线ans = ans + n-x;}System.out.println(ans);}}
