0
点赞
收藏
分享

微信扫一扫

梅森素数、猜年龄、啤酒饮料、武功秘籍、调和级数、李白打酒、猜字母、扩散、三升序列、寻找2020

梅森素数

题目

代码

	public void process() {
		BigInteger num = BigInteger.valueOf(2).pow(11213).subtract(BigInteger.ONE);
		String str = num+"";
		String answer = str.substring(str.length()-100);
		System.out.println(answer);
	}

小结

  1. 看见这种题目臭长的,先到最后看一眼问题

  2. BigInteger类方法

    • valueOf()

      参数是一个long值,返回BigInteger实例

    • pow()

      参数是一个int值,作为指数

    • substract()

      参数是一个BigInteger实例,减法运算

      可以用BigInteger.ONE;BigInteger.TEN;BigInteger.ZERO

  3. 返回字符串str后n位

    String answer = str.substring(str.length()-n);
    

猜年龄

题目

代码

	public void process() {
		for(int i = 1;i < 50;i++) {
			for(int j = 1;j < 50 ;j++) {
				if(i * j == (i + j) * 6 && Math.abs(i - j) <=8 && i != j) {
					System.out.println(i < j ? i : j);//10
				}
			}
		}
	}

小结

  1. 无趣

啤酒饮料

题目

代码

	public void process() {
		for(int i = 1;i < 50;i++) {
			for(int j = i ;j < 50;j++) {
				if(Math.abs(2.3 * i + 1.9 *j - 82.3) < 0.01) {
					System.out.println(i);
				}
			}
		}
	}

小结

  1. 避免浮点数的全等比较
    • 在一定“误差”内比较,数量级小于最小的,如 2.3 --> 0.01
    • 将 2.3 --> 23,扩大到整数再全等比较

武功秘籍

题目

代码

	public void process() {
		System.out.println(count(81, 92));
	}
	public int count(int a,int b) {
		int n = 0;
		while(a != b) {
			if(a % 2 == 1) n++;
			a++;
		}
		if(a % 2 == 0) n++;
		return n;
	}

小结

  1. 无趣

调和级数

题目

代码

	public void process() {
		double c = 0;
		for(double i = 1.0;;i++) {
			c += 1 / i;
			if(c - 15.0 > 0) {
				System.out.println((int)i);
				break;
			}
		}	
	}

小结

  1. 无趣,再看见普通的遍历就不写了

李白打酒

题目

代码

	public void process() {
		fun(5, 10, 2);
		System.out.println(count);//14
	}
	private int count = 0;	
	public void fun(int a,int b,int c) {
		if(c == 1 && a == 0 && b == 1) count++;
		if(a >= 0 && b >= 0 && c > 0) {
			fun(a -1, b, c * 2);
			fun(a, b-1, c - 1);
		}
	}

小结

  1. 比起递归返回一个值 ,我更喜欢用一个成员变量去累加,不用return

猜字母

题目

代码

	public void process() {
		String str = "abcdefghijklmnopqrs";
		StringBuilder sb = new StringBuilder();
		for(int i = 0;i < 106;i++) {
			sb.append(str);
		}
		while(sb.length() > 1){
			for(int i = 0;i < sb.length();i++) {
				sb.deleteCharAt(i);
			}
		}
		System.out.println(sb.toString());
	}

小结

  1. 有个小坑,是 i++,而不是 i += 2

    因为是针对本身删除,所以,删一个后,每个值的索引减 1,故只需 i++

扩散

题目

代码

	public void process() {
	    int a[][] =new int[10000][10000];
	    Set<String> hs1 = new HashSet<>();
	    Set<String> hs2 = new HashSet<>();
	    
	    a[5000][5000]=1;		a[5000+2020][5000+11]=1;
	    a[5000+11][5000+14]=1;	a[5000+2000][5000+2000]=1;
	    hs1.add("5000,5000");hs1.add("7020,5011");
	    hs1.add("5011,5014");hs1.add("7000,7000");
	
	    for (int i = 2; i < 2022; i++) {
	        for (String s : hs1) {
	            String[] arr = s.split(",");
	            int x=Integer.parseInt(arr[0]);
	            int y=Integer.parseInt(arr[1]);
	            if(a[x-1][y]==0){
	                a[x-1][y]=1;
	                hs2.add((x-1)+","+(y));
	            }
	            if(a[x][y-1]==0){
	                a[x][y-1]=1;
	                hs2.add((x)+","+(y-1));
	            }
	            if(a[x+1][y]==0){
	                a[x+1][y]=1;
	                hs2.add((x+1)+","+(y));
	            }
	            if(a[x][y+1]==0){
	                a[x][y+1]=1;
	                hs2.add((x)+","+(y+1));
	            }
	        }
	        hs1.clear();
	        hs1.addAll(hs2);
	        hs2.clear();
	    }
	    int count=0;
	    for (int i = 0; i < 10000; i++) {
	        for (int j = 0; j < 10000; j++) {
	            if(a[i][j]==1) count++;
	        }
	    }
	    System.out.println(count);
	}

en…还有超时的解法

	public void process() {
		Set<Cell> set = new HashSet<>();
		Set<Cell> rep = new HashSet<>();
		Set<Cell> tmp = new HashSet<>();
		set.add(new Cell(0, 0));set.add(new Cell(2020, 11));
		set.add(new Cell(11, 14));set.add(new Cell(2000, 2000));
		rep.addAll(set);
		for(int i = 0;i < 2020;i++) {			
			for(Cell cell : rep) {
				tmp.add(new Cell(cell.getX() - 1, cell.getY()));
				tmp.add(new Cell(cell.getX() + 1, cell.getY()));
				tmp.add(new Cell(cell.getX(), cell.getY() - 1));
				tmp.add(new Cell(cell.getX(), cell.getY() + 1));
			}
			rep.clear();
			rep.addAll(tmp);
			set.addAll(tmp);
			tmp.clear();
			System.out.println(set.size() + "*");
		}
		System.out.println(set.size());
	}
	class Cell {
		private int x;
		private int y;
		public Cell(int x,int y) {
			this.x = x;
			this.y = y;
		}
		public int getX() {
			return x;
		}
		public int getY() {
			return y;
		}
		@Override
		public int hashCode() {
			return x * 10 + y;
		}
		@Override
		public boolean equals(Object other) {
			if(other == this) return true;
			if(!(other instanceof Cell)) return false;
			Cell o = (Cell)other;
			return o.x == x && o.y == y;
		}
	}

小结

  1. 在层层扩展中,有用到两个序列,

    一个序列用来存储每次待处理的节点,接受遍历

    另一个序列存储每次扩展出来的节点

    然后来回倒值,使得每次都处理新扩展的节点

  2. 我好想用Hash的去重机制做啊

    在分钟少的情况下,还能出结果,

    但在2020分钟的情况下,却因为要存储千百万个对象而耗时太久

三升序列

题目

代码

    char[][] chs = new char[30][50];
    int[][] dir = { { 0, 1 }, { 1, 0 }, { 1, 1 }, { 1, -1 }, { -1, 1 } };
    int cnt = 0;
    public void init() {
    	try {
            BufferedReader in = new BufferedReader(new FileReader("src/March/threeIncrease.txt"));
            String str;
            int row = 0;
            
            while ((str = in.readLine()) != null) {
            	chs[row++] = str.toCharArray();
            }
		} catch (Exception e) {}
    }
	@Override
	public void process() {
		init();
        int ia, ib, iaa, ibb;
        for (int i = 0; i < 30; i++) {
            for (int j = 0; j < 50; j++) {
                for (int k = 0; k < 5; k++) {
                    ia = i;
                    ib = j;
                    while (true) {
                        ia += dir[k][0];
                        ib += dir[k][1];
                        iaa = ia;
                        ibb = ib;
                        if (ia < 0 || ib < 0 || ia >= 30 || ib >= 50) {
                            break;
                        }
                        while (true) {
                            iaa += dir[k][0];
                            ibb += dir[k][1];
                            if (iaa < 0 || ibb < 0 || iaa >= 30 || ibb >= 50) {
                                break;
                            }
                            if (chs[i][j] < chs[ia][ib] && chs[ia][ib] < chs[iaa][ibb]) {
                                cnt++;
                            }
                        }
                    }
                }
            }
        }
        System.out.println(cnt);
	}

小结

  1. 题意不好读,琢磨好方向,得出 int[][] dir
  2. 三个值的选择实现
    • char[i][j]通过两个for循环实现
    • char[ia][ij]char[i][j]确定的基础上,循环5个方向,逐渐累加步长实现
    • char[iaa][ibb]char[ia][ib]确定的基础上,仍沿其方向,逐渐累加步长实现
    • 直到越界,跳出循环

寻找2020

题目

代码

	char[][] chs;
	public void init() {
		ArrayList<String> list = new ArrayList<>();
		try {
			BufferedReader in = new BufferedReader(new FileReader("src/March/2020.txt"));
			String str;
			while((str = in.readLine()) != null) {
				list.add(str);
			}
			in.close();
		} catch (Exception e) {}

		chs = new char[list.size()][list.get(0).length()];
		int i = 0;
		for(String str : list) {
			chs[i++] = str.toCharArray();
		}
	}
	@Override
	public void process() {
		init();
		int row = chs.length;
		int column = chs[0].length;
		int cnt = 0;
		
		for(int i = 0;i < row;i++) {
			for(int j = 0;j < column;j++) {
				if(j + 3 < column &&
						chs[i][j] == '2' &&
						chs[i][j + 1] == '0' &&
						chs[i][j + 2] == '2' &&
						chs[i][j + 3] == '0')
					cnt++;
				if(i + 3 < row &&
						chs[i][j] == '2' &&
						chs[i + 1][j] == '0' &&
						chs[i + 2][j] == '2' &&
						chs[i + 3][j] == '0') 
					cnt++;
				if(i + 3 < row && j + 3 < column &&
						chs[i][j] == '2' &&
						chs[i + 1][j + 1] == '0' &&
						chs[i + 2][j + 2] == '2' &&
						chs[i + 3][j + 3] == '0') 
					cnt++;
			}
		}
		System.out.println(cnt);
	}

小结

  1. 此题是三升序列的的弟弟
  2. 处理文件,确定二维数组的大小处可供参考
举报
0 条评论