蓝桥杯JAVA笔记

//	获取输入整数的长度
String.valueOf(input).length() 

//	判断闰年
if((year%4==0&&year%100!=0)||(year%400==0))

//	整数转字符数组
 String str = 1234+"";
 char[] ch = str.toCharArray();
 
*****************输入问题
//	不能混合使用 next() 和 nextLine() 接收输入,也不能混合使用 nextInt() 和 nextLine() 接收。
Scanner in = new Scanner(System.in);
for (int i = 0; i < 3; i++) {
    
    
    int cur = in.nextInt();
    System.out.println(cur);
}
while (in.hasNextLine()) {
    
    
    String s = in.nextLine();
    System.out.println(s);
}
输入 :
1 2 3
abc
输出:
1
2
3
没有abc因为读入了nextLine换行符

*****************输入问题
//大胖子走迷宫
一个是String读入问题
for (int i = 1; i <= n; i++) {
    
    
			String mark = sc.next();
			for (int j = 1; j <= mark.length(); j++) {
    
    
				map[i][j] = mark.charAt(j - 1);
			}
		}
一个是思路问题(对队列的理解和运用不深刻),迷宫问题用BFS队列解决 停留相当于另一个选择 应该将其也入队 且必须在对头 。

*****************越界问题
//算数平方根 本质是查找 用二分查找
public static int mySqrt(int x) {
    
    
		if (x == 0)
			return 0;
		if (x == 1)
			return 1;
		int left = 0, right = x, result = 0;
		while (left <= right) {
    
    
			int mid = (left + right) / 2;
			if (x / mid == mid) {
    
    
				result = mid;
				break;
			} else if (mid > x / mid) {
    
    
				right = mid - 1;
				result = right;
			} else
				left = mid + 1;
		}
		return result;
	}
一开始写的判断条件是mid*mid==x,测试用例会越界,所以写判断条件的时候一定要考虑越界问题,应该为x/mid==mid,但此时有除法一定要考虑mid=0的特殊情况 mid=0有两种情况 (left + right)=0||(left + right)=1
所以要养成先判断特殊情况越界的习惯。

*****************位运算问题
//位1的运算
public class Solution {
    
    
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
    
    
        int count = 0;
        while (n != 0) {
    
    
            count += n & 1;
            n >>= 1;
        }
        return count;
    }
}
这段代码会无线循环 因为
算术右移 >> :舍弃最低位,高位用符号位填补;
逻辑右移 >>> :舍弃最低位,高位用 0 填补。
那么对于负数而言,其二进制最高位是 1,如果使用算术右移,那么高位填补的仍然是 1。也就是 n 永远不会为 0。所以代码会超时 。
在 Java 中需要使用逻辑右移,即 >>>while 的判断条件才能是 n != 0 。正确的代码如下:
public class Solution {
    
    
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
    
    
        int count = 0;
        while (n != 0) {
    
    
            count += n & 1;
            n >>>= 1;
        }
        return count;
    }
}
另外记录下
N&(N-1)==0可以判断N是否为二次幂
N&=(N-1)可以去除最右边一位1
N&1==0 判断偶数 这个比较常用

*****************越界问题
判断素数  一是因数总是成对 故只需要找一半就行 二是埃式塞思想得学会 DP可能会用到
public static int countPrimes(int n) {
    
    
		int count = 0;

		for (int i = 2; i < n; i++) {
    
    
			boolean a = true;
			for (int j = 2; j * j <= i; j++)
				if (i % j == 0) {
    
    
					a = false;
					break;
				}
			if (a) {
    
    
				count++;
			}
		}
		return count;
	}
	
	public static int countPrimes2(int n) {
    
    
		int count = 0;
		for (int i = 2; i < n; i++) {
    
    
			boolean a = true;
			  for(int j=2;j<=Math.sqrt(i);j++) 
				if (i % j == 0) {
    
    
					a = false;
					break;
				}
			if (a) {
    
    
				count++;
			}

		}
		return count;
	}
	
//	埃氏筛
	public static int countPrimes3(int n) {
    
    
		int count =0;
		int[] num=new int[n];
		Arrays.fill(num, 1);
		for(int i=2;i<n;i++)
		{
    
    
			if(num[i]==1)
				count++;
			for(int j=i;j<n;j+=i)
				num[j]=0;
		}
		return count;
}
sqrt运算还是很耗时的 最好用i*i

//动态规划 跳跃
public class tiaoyue {
    
    
	public static int[][] value = new int[101][101];
	public static int[][] dp = new int[101][101];
	public static int[][] step = new int[][] {
    
     {
    
     0, 1 }, {
    
     0, 2 }, {
    
     0, 3 }, {
    
     1, 0 }, {
    
     1, 1 }, {
    
     1, 2 }, {
    
     2, 0 },
			{
    
     2, 1 }, {
    
     3, 0 } };

	public static int dfs(int x, int y, int n, int m) {
    
    
	//动态规划 
	//省去重复递归 
		if (dp[x][y] != -1)
			return dp[x][y];
	//递归到终点后开始倒序构造dp数组 
		if (x == n && y == m)
			dp[x][y] = value[x][y];
		else {
    
    
			int max = -65536;
			//递归
			for (int i = 0; i < 9; i++) {
    
    
				if (x + step[i][0] <= n && y + step[i][1] <= m)
					max = (dfs(x + step[i][0], y + step[i][1], n, m) > max) ? dfs(x + step[i][0], y + step[i][1], n, m)
							: max;
			}
		//状态转换 
			dp[x][y] = max + value[x][y];
		}
		return dp[x][y];

	}

	public static void main(String args[]) {
    
    
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		int m = cin.nextInt();
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
				value[i][j] = cin.nextInt();
		for (int i = 1; i <= n; i++)
			Arrays.fill(dp[i], -1);
		System.out.print(dfs(1, 1, n, m));
		System.out.println();
	}
}

*****************double相关问题
这题问20*21个点确定多少直线
public class C {
    
    
//1 线段两点式都忘了  2斜率不一定是整数且斜率为无穷需要考虑进去 这里应该用double 注意double和int的用法 3 其次应该用Set 
	public static void main(String args[]) {
    
    
		ArrayList<String> kb = new ArrayList<String>();
		double k, b ;
		for (int x1 = 0; x1 < 20; x1++)
			for (int y1 = 0; y1 <= 20; y1++) 
				for (int x2 = x1+1; x2 < 20; x2++)
					for (int y2 = 0; y2 <= 20; y2++) {
    
    
						k=1.0*(y2 - y1) / (x2 - x1);
						b=1.0*(x2 * y1 - x1 * y2) / (x2 - x1);
						if (!kb.contains(k+","+b)) {
    
    
								kb.add((k+","+b));
							}
						} 	
		 System.out.println(kb.size()+20);
	}
}
蓝桥杯考完了 明年一定好好学 今年300白给了 哎

猜你喜欢

转载自blog.csdn.net/qq_39969848/article/details/129064237