编程题练习1

1. 牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值 a i a_i ai。现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人。牛牛发现队伍的水平值等于该队伍队员中第二高水平值。

例如:
一个队伍三个队员的水平值分别是3,3,3.那么队伍的水平值是3;
一个队伍三个队员的水平值分别是3,2,3.那么队伍的水平值是3;
一个队伍三个队员的水平值分别是1,5,2.那么队伍的水平值是2。
为了让比赛更有看点,牛牛想安排队伍使所有队伍的水平值总和最大。
如样例所示:
如果牛牛把6个队员划分到两个队伍,如果方案为:
team1:{1,2,5}, team2:{5,5,8}, 这时候水平值总和为7。
而如果方案为:
team1:{2,5,8}, team2:{1,5,5}, 这时候水平值总和为10。
没有比总和为10更大的方案,所以输出10。

输入描述:
输入的第一行为一个正整数n(1 ≤ n ≤ 10^5);
第二行包括3*n个整数a_i(1 ≤ a_i ≤ 10^9),表示每个参赛选手的水平值。
输出描述:
输出一个整数表示所有队伍的水平值总和最大值。

示例:
输入:
2
5 2 8 5 1 5
输出:
10

参考代码:

import java.util.Arrays;
import java.util.Scanner;
public class Main1 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while(scanner.hasNext()){
            int n = scanner.nextInt();
            scanner.nextLine();
            int[] arr = new int[3*n];
            for (int i=0;i<3*n;i++){
                arr[i] = scanner.nextInt();
            }
            Arrays.sort(arr);//对输入的队员水平值进行升序排序
            long sum = 0;
            for (int i= 3*n-2;i>=n;i -= 2){
                //由题意可知,每组的水平值是中间那个人的水平值,
                // 所以要保证最后所有组的水平总和值最大就需要保证每组的水平值是能分组类型中的最大值
                //即每组中的中等值一定是仅次于最大值的那个数,也就是排序后的3n-2,3n-4,3n-6……等数据相加!
                sum += arr[i];
            }
            System.out.println(sum);
        }
        scanner.close();
    }
}

2. 输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”。

输入描述:
每个测试输入包含2个字符串。
输出描述:
输出删除后的字符串。

示例:
输入:
They are students. aeiou
输出:
Thy r stdnts.

参考代码:

import java.util.Scanner;
public class Main2{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        String str1 = scanner.nextLine();
        String str2 = scanner.nextLine();
        String[] arr1 = str1.split(" ");
        StringBuffer stringbuffer = new StringBuffer();
        for (int i= 0;i < arr1.length;i++){
            if (!str2.contains(arr1[i])){
                stringbuffer.append(arr1[i]);
            }
        }
        System.out.println(stringbuffer.toString());
    }
}

3. 牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道他最少可以把这个数组分为几段排序子序列。
如样例所示,牛牛可以把数组A划分为[1,2,3]和[2,2,1]两个排序子序列,至少需要划分为2个排序子序列,所以输出2。

输入描述:
输入的第一行为一个正整数n(1 ≤ n ≤ 10^5);
第二行包括n个整数A_i(1 ≤ A_i ≤ 10^9),表示数组A的每个数字。
输出描述:
输出一个整数表示牛牛可以将A最少划分为多少段排序子序列。

示例:
输入:
6
1 2 3 2 2 1
输出:
2
参考代码:

import java.util.Scanner;
public class Main{
    /**首先理解:非递增——>a[i] >= a[i+1];非递减——>a[i] <= a[i+1]*/
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int arr[] = new int[n+1];
        //此处数组大小要+1是为了防止出现数组越界的情况,相当于最后一个元素默认为0
        for (int i=0;i<n;i++){
            arr[i] = scanner.nextInt();
        }
        int i = 0;
        int count = 0;
        while (i < n) {
            if (arr[i] < arr[i+1]){
                while(arr[i] < arr[i+1]){
                    i++;
                }
                count++;
                i++;
            }else if(arr[i] == arr[i+1]){
                i++;
            }else{
                while (i<n && arr[i] > arr[i+1]) {
                    i++;
                }
                count++;
                i++;
            }
        }
        System.out.println(count);
    }
}

4. 将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I。
输入描述:
每个测试输入包含1个测试用例: I like beijing. 输入用例长度不超过100。
输出描述:
依次输出倒置之后的字符串,以空格分割。

示例:
输入:I like beijing.
输出:beijing. like I

参考代码:

import java.util.LinkedList;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        int x = 0;
        LinkedList<Character> list = new LinkedList<>();
        for(int i = str.length();i>=1;i--){
            if (str.charAt(i) != ' '){
                char c = str.charAt(i);
                list.add(c);
                continue;
            }
            String str1 = "";
            while (list.size() > 0){
                str1 += list.removeLast();
            }
            System.out.print(str1);
        }
    }
}

5. 读入一个字符串str,输出字符串str中的连续最长的数字串。

输入描述:
个测试输入包含1个测试用例,一个字符串str,长度不超过255。
输出描述:
在一行内输出str中里连续最长的数字串。

示例:
输入:abcd12345ed125ss123456789
输出:123456789

参考代码:

import java.util.Scanner;
public class Main6 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String string = scanner.nextLine();
        String result = "";
        int count = 0;
        char[] arr = string.toCharArray();
        for (int i=0;i<arr.length;i++){  //此循环是找到以数字开头的地方
            if ('0' <= arr[i] && arr[i] <= '9'){
                count = 1;
                int index = i;
                for (int j = i+1;j<arr.length;j++){ //此循环是找有多少数字连续出现
                    if ('0' <= arr[j] && arr[j] <= '9'){
                        count++;
                        index = j;
                    }else{
                        break;
                    }
                }
                if (count > result.length()){   //此处判断后面出现的连续数字长度是否大于前面出现的数字连续长度
                    result = string.substring(i,index+1);
                }
            }else{
                continue;
            }
        }
        System.out.println(result);
    }
}

6. 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

参考代码:

public int MoreThanHalfNum_Solution(int [] array) {
        int res=0;
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int num:array){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        
        for(int key:map.keySet()){
            if(map.get(key)>(array.length/2)){
                res=key;
            }
        }
        return res;
    }

7. A,B,C三个人是好朋友,每个人手里都有一些糖果,我们不知道他们每个人手上具体有多少个糖果,但是我们知道以下的信息:
A - B, B - C, A + B, B + C。这四个数值,每个字母代表每个人所拥有的糖果数:
现在需要通过这四个数值计算出每个人手里有多少个糖果,即A,B,C。这里保证最多只有一组整数A,B,C满足所有题设条件。

参考代码:

import java.util.Scanner;
public class Main{
     public static void main(String[] args) {
         Scanner in = new Scanner(System.in);
         int y1,y2,y3,y4;
         float a,b,c;
         while (in.hasNextInt()) {
             y1 = in.nextInt();
             y2 = in.nextInt();
             y3 = in.nextInt();
             y4 = in.nextInt();
             a=(y1+y3)/ 2 ;
             b=(y3-y1)/ 2 ;
             c=(y4-y2)/ 2 ;
             if ((a-((y1+y3)/ 2 ))!= 0 ){
                 System.out.print( "No" );
                 return ;
             }
             if ((b-((y3-y1)/ 2 )!= 0 )||(b!=((y2+y4)/ 2 ))){
                 System.out.print( "No" );
                 return ;
             }
             if ((c-((y4-y2)/ 2 ))!= 0 ){
                 System.out.print( "No" );
             return ;
             }
             System.out.print(( int )a+ " " +( int )b+ " " +( int )c);
             }
     }
}

8. 给定一个十进制数M,以及需要转换的进制数N。将十进制数M转化为N进制数。

输入描述:输入为一行,M(32位整数)、N(2 ≤ N ≤ 16),以空格隔开。
输出描述:为每个测试实例输出转换后的数,每个输出占一行。如果N大于9,则对应的数字规则参考16进制(比如,10用A表示,等等)。

示例:
输入:7 2
输出:111

参考代码:

import java.lang.StringBuffer;
public class Main {
	public String solve (int M, int N) {
		if(M == 0){
		return "0";
	}
	boolean flag = true;
	if(M < 0){
		M = -M;
		flag = false;
	}
	StringBuffer res = new StringBuffer();
	String hex = "0123456789ABCDEF";
	while(M !=0){
		res.append(hex.charAt(M % N));
		M = M / N;
	}
	if(flag == true){
		return res.reverse().toString();
	}else{
		return "-"+res.reverse().toString();
		}
	}
}

9. “回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。花花非常喜欢这种拥有对称美的回文串,生日的时候她得到两个礼物分别是字符串A和字符串B。现在她非常好奇有没有办法将字符串B插入字符串A使产生的字符串是一个回文串。你接受花花的请求,帮助她寻找有多少种插入办法可以使新串是一个回文串。如果字符串B插入的位置不同就考虑为不一样的办法。
例如:
A = “aba”,B = “b”。这里有4种把B插入A的办法:
在A的第一个字母之前: “baba” 不是回文;
在第一个字母‘a’之后: “abba” 是回文;
在字母‘b’之后: “abba” 是回文;
在第二个字母’a’之后 “abab” 不是回文。
所以满足条件的答案为 2。

输入描述:
每组输入数据共两行。
第一行为字符串A;
第二行为字符串B。
字符串长度均小于100且只包含小写字母。
输出描述:
输出一个数字,表示把字符串B插入字符串A之后构成一个回文串的方法数。

参考代码:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str1 = scanner.nextLine();
        String str2 = scanner.nextLine();
        int count = 0;
        for (int i=0;i<str1.length();i++){
            StringBuilder stringBuilder = new StringBuilder(str1);
            stringBuilder.insert(i,str2);
            if (isHuiWen(stringBuilder.toString())){
                count++;
            }
        }
        System.out.println(count);
    }

    public static boolean isHuiWen(String string) {
        int i= 0;
        int j= string.length();
        while(i<j){
            if (string.charAt(i) != string.charAt(j)){
                return false;
            }
            i++;
            j--;
        }
        return true;
    }
}

10. 一个数组有 N 个元素,求连续子数组的最大和。 例如:[-1,2,1],和最大的连续子数组为[2,1],其和为 3

输入描述:
输入为两行。 第一行一个整数n(1 <= n <= 100000),表示一共有n个元素 第二行为n个数,即每个元素,每个整数都在32位int范围内。以空格分隔。
输出描述:
所有连续子数组中和最大的值。

示例:
输入:3 -1 2 1
输出:3

参考代码:

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int[] num = new int[n];
		for(int i=0; i<n; i++){
			num[i] = in.nextInt();
		}
		int sum = num[0];
		int max = num[0];
		for(int i=1; i<n; i++){
			sum = Math.max(sum,0)+num[i];
			if(max < sum){
				max = sum;
			}
		}
		System.out.println(max);
	   }
}

11. 二货小易有一个W*H的网格盒子,网格的行编号为0-(H-1),网格的列编号为0-(W-1)。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。
对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为:( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根。小易想知道最多可以放多少块蛋糕在网格盒子里。

输入描述:每组数组包含网格长宽W,H,用空格分割.(1 ≤ W、H ≤ 1000)。
输出描述:输出一个最多可以放的蛋糕数。

示例:
输入:3 2
输出:4

参考代码:

分析:分析题节目中的欧几里得距离要等于2,从数学角度来看,如果分别把 (x1-x2) * (x1-x2)和(y1-y2) * (y1-y2)看作是一个整体的话,那么这两个整体不可以同时分别为(1,3),(3,1),(2,2),(0,4),(4,0)这样的数值,最后结合实际题意,只有(0,4)和(4,0)符合题意,那么就会得到这样一个表达式:{x1=x2,y1-y2=2}和{y1=y2,x1-x2=2}。但是题目要求,任意两块蛋糕的欧几里得距离不能等于2.这就是说,如果蛋糕的位置为[i][j],那么位置为[i+2][j]和[i][j+2]就不可以再放蛋糕了。

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int w = scanner.nextInt();
        int h = scanner.nextInt();
        int count = 0;
        int[][] array = new int[w][h];
        for (int i=0;i<w;i++){
            for (int j=0;j<h;j++){
                if (array[i][j] ==0){  //0表示可以放蛋糕,1表示不可以放蛋糕。
                    count++;
                    if (i+2<w){
                        array[i+2][j]=1;
                    }
                    if (j+2<w){
                        array[i][j+2]=1;
                    }
                }
            }
        }
        System.out.println(count);
    }
}

12. 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。

输入描述:输入一个字符串,包括数字字母符号,可以为空。
输出描述:如果是合法的数值表达则返回该数字,否则返回0。

示例:
输入:
+2147483647
1a33
输出:
2147483647
0

参考代码:

// sum = sum*10 + string[i] - '0' --->这个公式是将整数字符串转变为整数的关键!
public class Main {
    public int StrToInt(String str){
        char[] arr = str.toCharArray(); 
        if (arr == null || arr.length==0){
            return 0;
        }
        
        int flag = 1;
        if (arr[0] == '-'){
            flag = -1;
            arr[0] ='0';
        }else if(arr[0] == '+'){
            flag = 1;
        }
        
        int sum =0;
        for (int i=0;i<arr.length;i++){  
            if (arr[i]<'0' || arr[i]>'9'){
                sum=0;
                break;
            }
            sum = sum*10 + arr[i]-'0';
        }
        return  flag*sum;
    }
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值