zoukankan      html  css  js  c++  java
  • 52-2018 蓝桥杯省赛 B 组模拟赛(一)java

    最近蒜头君喜欢上了U型数字,所谓U型数字,就是这个数字的每一位先严格单调递减,后严格单调递增。比如 212212 就是一个U型数字,但是 333333, 9898, 567567, 3131331313,就是不是U型数字。

    现在蒜头君问你,[1,100000][1,100000] 有多少U型数字?

    提示:请不要输出多余的符号。

    import java.util.Scanner;
    
    public class Main1{
    	public static String mp[] = new String[11];
    	public static int[][] visit = new int[11][11];
    	public static int n, m, ans;
    	public static int dx[] = {0, 0, 1, -1};
    	public static int dy[] = {1, -1, 0, 0};
    	
    	public static void main(String[] args) {
    		Scanner cin = new Scanner(System.in);
    		
    		ans = 0;
    		//[1,100000] 有多少U型数字?
    		for(int i = 100; i <= 100000 ; i++) {
    			int a[] = new int[10];
    			int t = i;
    			int ct = 0;
    			while(t!=0) {
    				a[ct++] = t % 10;
    				t /= 10;
    			}
    			int jiang = 0;
    			int zeng = 0;
    			int f = 0;
    			int f1 = 0;
    			int f2 = 0;
    			for(int j = 1; j < ct; j++) {
    				if(a[j] < a[j - 1] && f1 == 0) {
    					jiang = 1;
    					f2 = 1;
    				}
    				else if(a[j] > a[j - 1] && f2 == 1) {
    					zeng = 1;
    					f1 = 1;
    				}
    				else {
    					f = -1;
    					break;
    				}
    			}
    			if(f != -1 && f1 == 1 && f2 == 1) {
    				ans++;
    			}
    		}
    		
    		System.out.println(ans);
    	}
    }
    

      

    2.相信大家都知道什么是全排列,但是今天的全排列比你想象中的难一点。我们要找的是全排列中,排列结果互不相同的个数。比如:aab 的全排列就只有三种,那就是aab,baa,aba

    代码框中的代码是一种实现,请分析并填写缺失的代码。

    import java.util.*;
    import java.math.*;
    
    public class Main {
        public static final int N = 1000;
        public static char[] str = new char[N];
        public static char[] buf = new char[N];
        public static int[] vis = new int[N];
        public static int total = 0;
        public static int len = 0;
    
        public static void arrange(int num) {
            if (num == len) {
                for (int i = 0; i < len; ++i) {
                    System.out.print(buf[i]);
                }
                System.out.println();
                total++;
                return;
            }
            for (int i = 0; i < len; ++i) {
                if (vis[i] == 0) {
                    int j = 0;
                    for (j = i + 1; j < len; ++j) {
                        if (/*在这里填写必要的代码*/) {
                            break;
                        }
                    }
                    if (j == len) {
                        vis[i] = 1;
                        buf[num] = str[i];
                        arrange(num + 1);
                        vis[i]= 0;
                    }
                }
            }
        }
    
        public static void main(String[] args) {
            Scanner cin = new Scanner(System.in);
            str = cin.next().toCharArray();
            total = 0;
            len = str.length;
            buf[len] = '';
            int i = 0, j = 0;
            for (i = 0; i < len; ++i) {
                for (j = i + 1; j < len; ++j) {
                    if (str[i] > str[j]) {
                		char tmp = str[i];
                		str[i] = str[j];
                		str[j] = tmp;
            		}
                }
            }
            arrange(0);
            System.out.println("Total " + total);
        }
    }
    

      

    思路: 就是已经遍历过的就不要重复遍历,可以手动模拟下试试,aaab:   假如 aaab已经用过了, 这次第一个入buf的是第二个a, 然后他从头开始遍历时,发现以前已经用过a了,就不要在用了。

    if (str[i] == str[j] && vis[j] == 1) {
                        	//https://nanti.jisuanke.com/t/A1601
                            break;
                        }
    

      

    3.对于一个含有 n+2n+2 个元素的数列,A_0, A_1, cdots A_nA0,A1,An,满足这样的递归公式

    displaystyle A_i = frac{A_{i-1} + A_{i + 1}}{2} - C_i 1 le i le nAi=2Ai1+Ai+1Ci   1in

    现在我们知道 A_0, A_{n + 1}A0,An+1 和 C_1, C_2, cdots C_nC1,C2,Cn

    现在请你帮忙计算 A_1A1 的值。

    输入格式

    第一行输入一个整数 n(1 le n le 1000)n(1n1000)。

    第二行输入两个数 A_0A0 和 A_{n+1}An+1,接着是 nn 个数据分别是 C_1,C_2, cdots C_nC1,C2,Cn。所有的数据均是两位小数的浮点数。

    输出格式

    输出 A_1A1 的值,结果保留两位小数。

    样例输入1

    1
    50.50 25.50
    10.15

    样例输出1

    27.85

    样例输入2

    2
    -756.89 52.52
    172.22 67.17

    样例输出2

    -761.49

    java超时:
     for(int i = 2; i <= n + 1; i++) {
            	t.x = 2 * a1.x - a0.x;
            	t.z = 2 * a1.z - a0.z + 2 * c[i - 1];
            	a0 = a1;
            	a1 = t;
    //        	System.out.println(t.x + " " + t.z);
            }
    

      

    上面的 a0, a1,t 都是对象,这个赋值会很耗时间,使效率很低。

     
     
            xx a0 = new xx(0, a[0]);
            xx a1 = new xx(1, 0);
            xx t = new xx(0, 0);
            for(int i = 2; i <= n + 1; i++) {
            	t.x = 2 * a1.x - a0.x;
            	t.z = 2 * a1.z - a0.z + 2 * c[i - 1];
            	a0.x = a1.x;
                a0.z = a1.z;
            	a1.x = t.x;
                a1.z = t.z;
    //        	System.out.println(t.x + " " + t.z);
            }
            System.out.printf("%.2f
    ",(a[n+1] - a1.z) / a1.x);
    

      

    完整答案:

    import java.util.*;
    import java.math.*;
    
    public class Main {
    
        public static void main(String[] args) {
            Scanner cin = new Scanner(System.in);
            double a[] = new double[1003];
            double c[] = new double[1003];
            
            int n = cin.nextInt();
    //        a[0] = cin.nextDouble();
            a[0] = cin.nextDouble();
            a[n+1] = cin.nextDouble();
            
            for(int i = 1; i <= n; i++) {
            	c[i] = cin.nextDouble();
            }
            
            double d = 0;
            double dx = 1;
            xx a0 = new xx(0, a[0]);
            xx a1 = new xx(1, 0);
            xx t = new xx(0, 0);
            for(int i = 2; i <= n + 1; i++) {
            	t.x = 2 * a1.x - a0.x;
            	t.z = 2 * a1.z - a0.z + 2 * c[i - 1];
            	a0.x = a1.x;
                a0.z = a1.z;
            	a1.x = t.x;
                a1.z = t.z;
    //        	System.out.println(t.x + " " + t.z);
            }
            System.out.printf("%.2f
    ",(a[n+1] - a1.z) / a1.x);
            
        }
    }
    class xx{
    	double x;
    	double z;
    	xx(){
    		
    	}
    	xx(double x, double z){
    		this.x = x;
    		this.z = z;
    	}
    }
    /*
     2
    1 12
    1 2
     */
    

      

    4.蒜头君被暗黑军团包围在一座岛上,所有通往近卫军团的路都有暗黑军团把手。幸运的是,小岛上有一扇上古之神打造的封印之门,可以通往近卫军团,传闻至今没有人能解除封印。

    封印之门上有一串文字,只包含小写字母,有 kk 种操作规则,每个规则可以把一个字符变换成另外一个字符。经过任意多次操作以后,最后如果能把封印之门上的文字变换成解开封印之门的文字,封印之门将会开启。

    蒜头君战斗力超强,但是不擅计算,请你帮忙蒜头君计算至少需要操作多少次才能解开封印之门。

    输入格式

    输入第一行一个字符串,长度不大于 10001000,只包含小写字母,表示封印之门上的文字。

    输入第二行一个字符串,只包含小写字母,保证长度和第一个字符串相等,表示能解开封印之门的文字。

    输入第三行一个整数 k(0 le k le 676)k(0k676)。

    接下来 kk 行,每行输出两个空格隔开的字符 aa, bb,表示一次操作能把字符 aa 变换成字符 bb。

    输出格式

    如果蒜头君能开启封印之门,输出最少的操作次数。否则输出一行 -11。

    样例输入

    abcd
    dddd
    3
    a b
    b c
    c d

    样例输出

    6

    思路: 转为最短路径问题.

    java交题经验:

    1. 读一行提取两个数字,比读两次要快。
    //        	char a = cin.next().charAt(0);
    //        	char b = cin.next().charAt(0);
            	String t = cin.nextLine();
    //        	System.out.println(t + "--");
            	char a = t.charAt(0);
            	char b = t.charAt(2);
    

     2. String.charAt() 比 将string 转为 char 数组取数要慢, 差别在这题中影响很小。

    String s1 = cin.next();
            String s2 = cin.next();
            st = s1.toCharArray();  // 转为数组要快
            end = s2.toCharArray();
    

      




    import java.util.*;
    import java.math.*;
    
    public class Main {
    	public static int[][] mp = new int[55][55];
    	
        public static void main(String[] args) {
            Scanner cin = new Scanner(System.in);
            String s1 = cin.next();
            String s2 = cin.next();
            
            int kk = cin.nextInt();
    //        System.out.println(s1 + "; " + s2 + "; " + kk);
            for(int i = 0; i < 26; i++) {
        		for(int j = 0; j < 26; j++) {
        			mp[i][j] = 999;
        			mp[i][i] = 0;
        		}
        	}
            cin.nextLine();
            for(int i = 0; i < kk; i++) {
    //        	char a = cin.next().charAt(0);
    //        	char b = cin.next().charAt(0);
            	String t = cin.nextLine();
    //        	System.out.println(t + "--");
            	char a = t.charAt(0);
            	char b = t.charAt(2);
            	if(a != b)
     		       	mp[a - 'a'][b - 'a'] = 1;
            }
            
            for(int k = 0; k < 26; k++) {
            	for(int i = 0; i < 26; i++) {
            		for(int j = 0; j < 26; j++) {
            			if(mp[i][j] > mp[i][k] + mp[k][j]) {
            				mp[i][j] = mp[i][k] + mp[k][j];
            			}
            		}
            	}
            }
            int ans = 0;
            int len = s1.length();
            for(int i = 0; i < len; i++) {
                int x = mp[s1.charAt(i) - 'a'][s2.charAt(i) - 'a'];
            	if(x < 999){
                    ans += x;
                }
                else{
                    ans = -1;
                    break;
                }
            }
            System.out.println(ans);
        }
    }
     
    /*
    abcd
    dddd
    3
    a b
    b c
    c d
     */
    

      

    import java.util.*;
    import java.math.*;
    
    public class Main {
    	public static int[][] mp = new int[55][55];
    	public static char[] st = new char[1005];
    	public static char[] end = new char[1005];
    	
        public static void main(String[] args) {
            Scanner cin = new Scanner(System.in);
            String s1 = cin.next();
            String s2 = cin.next();
            st = s1.toCharArray();  // 转为数组要快
            end = s2.toCharArray();
            
            int kk = cin.nextInt();
     
            for(int i = 0; i < 26; i++) {
        		for(int j = 0; j < 26; j++) {
        			mp[i][j] = 999;
        			mp[i][i] = 0;  // 自己到自己是0
        		}
        	}
     
            for(int i = 0; i < kk; i++) {
            	char a = cin.next().charAt(0);
            	char b = cin.next().charAt(0);
            	if(a != b)  // 注意
            		mp[a - 'a'][b - 'a'] = 1;
            }
            
            for(int k = 0; k < 26; k++) {
            	for(int i = 0; i < 26; i++) {
            		for(int j = 0; j < 26; j++) {
            			if(mp[i][j] > mp[i][k] + mp[k][j]) {
            				mp[i][j] = mp[i][k] + mp[k][j];
            			}
            		}
            	}
            }
            int ans = 0;
            int len = s1.length();
            for(int i = 0; i < len; i++) {
            	int x = mp[st[i] - 'a'][end[i] - 'a'];
            	if(x < 999){
                    ans += x;
                }
                else{
                    ans = -1;
                    break;
                }
            }
            System.out.println(ans);
        }
    }
     
    /*
    abcd
    dddd
    3
    a b
    b c
    c d
     */
    

      

    import java.util.*;
    import java.math.*;
    
    public class Main {
    	public static int[][] mp = new int[55][55];
    	
        public static void main(String[] args) {
            Scanner cin = new Scanner(System.in);
            String s1 = cin.next();
            String s2 = cin.next();
            
            int kk = cin.nextInt();
    //        System.out.println(s1 + "; " + s2 + "; " + kk);
            for(int i = 0; i < 26; i++) {
        		for(int j = 0; j < 26; j++) {
        			mp[i][j] = 999;
        			mp[i][i] = 0;
        		}
        	}
            cin.nextLine();
            for(int i = 0; i < kk; i++) {
    //        	char a = cin.next().charAt(0);
    //        	char b = cin.next().charAt(0);
            	String t = cin.nextLine();
    //        	System.out.println(t + "--");
            	char a = t.charAt(0);
            	char b = t.charAt(2);
            	if(a != b)
     		       	mp[a - 'a'][b - 'a'] = 1;
            }
            
            for(int k = 0; k < 26; k++) {
            	for(int i = 0; i < 26; i++) {
            		for(int j = 0; j < 26; j++) {
            			if(mp[i][j] > mp[i][k] + mp[k][j]) {
            				mp[i][j] = mp[i][k] + mp[k][j];
            			}
            		}
            	}
            }
            int ans = 0;
            int len = s1.length();
            for(int i = 0; i < len; i++) {
                int x = mp[s1.charAt(i) - 'a'][s2.charAt(i) - 'a'];
            	if(x < 999){
                    ans += x;
                }
                else{
                    ans = -1;
                    break;
                }
            }
            System.out.println(ans);
        }
    }
     
    /*
    abcd
    dddd
    3
    a b
    b c
    c d
     */
    

      

    
    

    5.在一个星光摧残的夜晚,蒜头君一颗一颗的数这天上的星星。

    蒜头君给在天上巧妙的画了一个直角坐标系,让所有的星星都分布在第一象。天上有 nn 颗星星,他能知道每一颗星星的坐标和亮度。

    现在,蒜头君问自己 qq 次,每次他问自己每个矩形区域的星星的亮度和是多少(包含边界上的星星)。

    输入格式

    第一行输入一个整数 n(1 le n le 50000)n(1n50000) 表示星星的数量。

    接下里 nn 行,每行输入三个整数 x,y,w(0 le x, y, wle 2000)x,y,w(0x,y,w2000),表示在坐标 (x,y)(x,y) 有一颗亮度为 ww 的星星。注意一个点可能有多个星星。

    接下来一行输入一个整数 q(1 le q le 50000)q(1q50000),表示查询的次数。

    接下来 qq 行,每行输入四个整数 x_1, y_1, x_2, y_2x1,y1,x2,y2,其中 (x_1, y_1)(x1,y1) 表示查询的矩形的左下角的坐标,(x_2, y_2)(x2,y2) 表示查询的矩形的右上角的坐标,0 le x_1 le x_2 le 20000x1x22000,0 le y_1 le y_2 le 20000y1y22000。

    输出格式

    对于每一次查询,输出一行一个整数,表示查询的矩形区域内的星星的亮度总和。

    样例输入

    5
    5 0 6
    7 9 7
    8 6 13
    9 7 1
    3 0 19
    4
    0 8 7 9
    0 0 7 10
    2 7 10 9
    5 4 7 5

    样例输出

    7
    32
    8
    0

    题目来源

    2018 蓝桥杯省赛 A 组模拟赛(一)


    思路:本题思路很简单,就是一个dp, 但是有许多注意点,对于c++而言搞一个额外数组标记就可以过,对于java而言,要优化许多才能过,因为java运行慢,输入输出也贼慢。
    import java.util.ArrayDeque;
    import java.util.Queue;
    import java.util.Scanner;
    import java.util.Stack;
    
    public class Main {
    	public static int[][] mp = new int[2002][2002];
    	public static int[][] dp = new int[2002][2002];
    	//优化1:加一个数据标记是否已经访问过,因为有大量的0,所以不能借用dp来判断(本题关键优化点)
    	public static int[][] visit = new int[2002][2002];
    	
        public static void main(String[] args) {
            Scanner cin = new Scanner(System.in);
            int n = cin.nextInt();
            int x, y, w;
    //        int max_x = 0, max_y = 0;
            for(int i = 0; i < n; i++) {
            	x = cin.nextInt();
            	y = cin.nextInt();
            	w = cin.nextInt();
            	mp[x][y] += w;
    //        	max_x = Math.max(x, max_x);    //删了:已通过 6 组测试数据,共 10 组
    //        	max_y = Math.max(y, max_y);
            }
            // 优化3: 一次访问到允许范围的最大比较好,应为访问的范围必须覆盖后面询问的最大范围,不能用有星星的最大
            dfs(2000, 2000);
            
            int t = 0;
            int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
            t = cin.nextInt();
    //        cin.nextLine();
            StringBuilder sb = new StringBuilder();
            for(int i = 0; i < t; i++) {
            	x1 = cin.nextInt();
            	y1 = cin.nextInt();
            	x2 = cin.nextInt();
            	y2 = cin.nextInt();
            	
    //        	// 优化2:(本题中优化效果不好,因为后面要提取数组,反而麻烦,要是单个字符就比较好) 只读一次,即一次只读一行, 但是注意,在nextInt()面用nextLine()必须在两者直接在用一个nextLine()
    //        	String xx = cin.nextLine();
    ////        	System.out.println(xx);
    //        	String[] data = xx.split(" ");
    ////        	for(String xy : data) {
    ////        		System.out.println(xy + "-");
    ////        	}
    ////        	System.out.println(xx.split(" ")[3]);
    //        	x1 = Integer.valueOf(data[0]);
    //        	y1 = Integer.valueOf(data[1]);
    //        	x2 = Integer.valueOf(data[2]);
    //        	y2 = Integer.valueOf(data[3]);
            	
            	int allw = 0;
            	allw += dp[x2][y2];
            	if(x1 - 1 >= 0) {
            		allw -= dp[x1-1][y2];
            	}
            	if(y1 - 1 >= 0) {
            		allw -= dp[x2][y1-1];
            	}
            	if(x1 - 1 >= 0 && y1 - 1 >= 0) {
            		allw += dp[x1-1][y1-1];
            	}
            	// 优化4:本题有大量输出,如果每次输出时耗时较大,可以拼接为一个字符串一起输出(本题关键优化点)
    //        	System.out.println(allw);
            	sb.append(String.valueOf(allw) + "
    ");  
            }
            System.out.println(sb);
    //        for(int i = 0; i <= max_x; i++) {
    //        	for(int j = 0; j <= max_y; j++) {
    //        		System.out.printf("%5d", dp[i][j]);
    //        	}
    //        	System.out.println();
    //        }
        }
        
        public static int dfs(int x, int y) {
        	if(visit[x][y] != 0) {
        		visit[x][y] = 1;
        		return dp[x][y];
        	}
        	if(x == 0 && y == 0) {
        		dp[x][y] = mp[x][y];
        		visit[x][y] = 1;
        		return dp[x][y];
        	}
        	if(x == 0) {
        		visit[x][y] = 1;
        		return dp[x][y] = mp[x][y] + dfs(x, y - 1);
        	}
        	if(y == 0) {
        		visit[x][y] = 1;
        		return dp[x][y] = mp[x][y] + dfs(x - 1, y);
        	}
        	visit[x][y] = 1;
        	return dp[x][y] = mp[x][y] + dfs(x, y - 1) + dfs(x - 1, y) - dfs(x - 1, y -1);
        }
        
    }
     
    /*
    5
    5 0 6
    7 9 7
    8 6 13
    9 7 1
    3 0 19
    4
    0 8 7 9
    0 0 7 10
    2 7 10 9
    5 4 7 5
    
    5
    1 1 1
    2 2 2
    3 3 3
    4 4 4
    2 4 1
    3
    0 0 1 1
    0 0 2 4
    1 1 4 4
    
    
    5
    5 0 6
    7 9 7
    8 6 13
    9 7 1
    3 0 19
    1
    0 0 7 10
     */
    

      

  • 相关阅读:
    js调试技巧
    Java编程技巧——构建器
    java设计模式:工厂方法模式(Factory Method)
    23种设计模式导航
    java设计模式:单例模式(Singleton Pattern)
    迭代器与生成器
    装饰器
    文件操作的说明与使用
    函数命名、调用小技巧
    各类型数据的操作方法
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/10575826.html
Copyright © 2011-2022 走看看