OpenJudge - Java程序设计例题(41-60)

目录

41:小孩报数问题

42:班级排名

43:谁拿了最多奖学金

44:生日相同

45:扩号匹配

46:集合合并

47:字符串排序

48:最远距离

49:竞赛评分

50:素数回文数的个数

51:验证“歌德巴赫猜想”

52:肿瘤检测

53:不吉利日期

54:数制转换

55:谁考了第k名

56:奇数单增序列

57:整数奇偶排序

58:整数去重

59:接水问题

60:二进制分类


41:小孩报数问题

描述

有N个小孩围成一圈,给他们从1开始依次编号,现指定从第W个开始报数,报到第S个时,该小孩出列,然后从下一个小孩开始报数,仍是报到S个出列,如此重复下去,直到所有的小孩都出列(总人数不足S个时将循环报数),求小孩出列的顺序。

输入

第一行输入小孩的人数N(N<=64)
接下来每行输入一个小孩的名字(人名不超过15个字符)
最后一行输入asdasdasdasdW,S (W < N),用逗号”,”间隔

输出

按人名输出小孩按顺序出列的顺序,每行输出一个人名

样例输入

5
Xiaoming
Xiaohua
Xiaowang
Zhangsan
Lisi
2,3

样例输出

Zhangsan
Xiaohua
Xiaoming
Xiaowang
Lisi

提示

可用链表来实现

import java.util.Scanner;
import java.util.LinkedList;
import java.util.List;
 
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        List<String> children = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            children.add(sc.next());
        }
        String[] s = sc.next().split(",");
        int a = Integer.parseInt(s[0]);
        int b = Integer.parseInt(s[1]);
        for (int i = 0; i < a - 1; i++) {
            children.add(children.remove(0));
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < b - 1; j++) {
                children.add(children.remove(0));
            }
            System.out.println(children.remove(0));
        }
    }
}

42:班级排名

描述

信息科学技术学院年终评定讲学金,需要对整个年级的学生按照平均分数进行排名.
要求:根据输入的学号和平均成绩,按照平均成绩降序输出学号
如果平均成绩相同,按照输入的顺序输出。

输入

第一行为N,表示输入N位学生的信息,接着的N行输入学生信息,1<=N<=500
学生信息的格式为:学号 平均成绩
学号的长度小于10,平均成绩在1-100之间.

输出

按照平均成绩降序输出学号,如果平均成绩相同,按照输入顺序输出

样例输入

        5
        10948001 80
        10948004 90
        10948101 95
        10948102 80
        10948209 90

样例输出

        10948101
        10948004
        10948209
        10948001
        10948102

import java.util.Scanner;
import java.util.Arrays;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();// 输入N位学生的信息
		Student[] students = new Student[N];
		for (int i = 0; i < N; i++) {
			students[i] = new Student(sc.next(), sc.nextInt());
		}
		 Arrays.sort(students, (a, b) -> b.grade - a.grade);
		 for (Student student : students) {
	            System.out.println(student.toString());
		}
	}
}

class Student {
	String sno; // 学号
	int grade; // 平均成绩

	public Student(String sno, int grade) {
		super();
		this.sno = sno;
		this.grade = grade;
	}

	@Override
	public String toString() {
		return sno ;
	}

}

43:谁拿了最多奖学金

描述

某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种,获取的条件各自不同:

1) 院士奖学金,每人8000元,期末平均成绩高于80分(>80),并且在本学期内发表1篇或1篇以上论文的学生均可获得;
2) 五四奖学金,每人4000元,期末平均成绩高于85分(>85),并且班级评议成绩高于80分(>80)的学生均可获得;
3) 成绩优秀奖,每人2000元,期末平均成绩高于90分(>90)的学生均可获得;
4) 西部奖学金,每人1000元,期末平均成绩高于85分(>85)的西部省份学生均可获得;
5) 班级贡献奖,每人850元,班级评议成绩高于80分(>80)的学生干部均可获得;

只要符合条件就可以得奖,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。例如姚林的期末平均成绩是87分,班级评议成绩82分,同时他还是一位学生干部,那么他可以同时获得五四奖学金和班级贡献奖,奖金总数是4850元。

现在给出若干学生的相关数据,请计算哪些同学获得的奖金总数最高(假设总有同学能满足获得奖学金的条件)。

输入

输入的第一行是一个整数N(1 <= N <= 100),表示学生的总数。接下来的N行每行是一位学生的数据,从左向右依次是姓名,期末平均成绩,班级评议成绩,是否是学生干部,是否是西部省份学生,以及发表的论文数。姓名是由大小写英文字母组成的长度不超过20的字符串(不含空格);期末平均成绩和班级评议成绩都是0到100之间的整数(包括0和100);是否是学生干部和是否是西部省份学生分别用一个字符表示,Y表示是,N表示不是;发表的论文数是0到10的整数(包括0和10)。每两个相邻数据项之间用一个空格分隔。

输出

输出包括三行,第一行是获得最多奖金的学生的姓名,第二行是这名学生获得的奖金总数。如果有两位或两位以上的学生获得的奖金最多,输出他们之中在输入文件中出现最早的学生的姓名。第三行是这N个学生获得的奖学金的总数。

样例输入

4
YaoLin 87 82 Y N 0
ChenRuiyi 88 78 N Y 1
LiXin 92 88 N N 0
ZhangQin 83 87 Y N 1

样例输出

ChenRuiyi
9000
28700

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		List<Student> stList = new ArrayList<Student>();
		int N = sc.nextInt(); // 学生的总数
		for (int i = 1; i <= N; i++) {
			stList.add(new Student(sc.next(), sc.nextInt(), sc.nextInt(), sc.next(), sc.next(), sc.nextInt()));
		}
		Collections.sort(stList);
		System.out.println(stList.get(0).name); // 获得最多奖金的学生的姓名
		System.out.println(stList.get(0).money); // 获得最多奖金的学生的奖金总数
		System.out.print(Student.total); // 这N个学生获得的奖学金的总数
	}
}

class Student implements Comparable<Student> {
	String name; // name姓名
	int qimo, pingyi; // qimo期末平均成绩、pingyi班级评议成绩
	String ganbu, xibu; // ganbu是否是学生干部、xibu是否是西部省份学生
	int lunwen; // lunwen发表的论文数

	static int total = 0;
	int money = 0;

	public Student(String name, int qimo, int pingyi, String ganbu,
			String xibu, int lunwen) {
		super();
		this.name = name;
		this.qimo = qimo;
		this.pingyi = pingyi;
		this.ganbu = ganbu;
		this.xibu = xibu;
		this.lunwen = lunwen;
		jisuan();
		total += money; // 这N个学生获得的奖学金的总数
	}

	void jisuan() { // 计算发放的奖学金数量
		if (qimo > 80 && lunwen >= 1) { // 院士奖学金
			money += 8000;
		}
		if (qimo > 85 && pingyi > 80) { // 五四奖学金
			money += 4000;
		}
		if (qimo > 90) { // 成绩优秀奖
			money += 2000;
		}
		if (qimo > 85 && xibu.equals("Y")) { // 西部奖学金
			money += 1000;
		}
		if (pingyi > 80 && ganbu.equals("Y")) { // 班级贡献奖
			money += 850;
		}
	}

	@Override
	public int compareTo(Student st) {
		// TODO Auto-generated method stub
		return st.money - money;
	}
}

44:生日相同

描述

在一个有180人的大班级中,存在两个人生日相同的概率非常大,现给出每个学生的学号,出生月日。试找出所有生日相同的学生。

输入

第一行为整数n,表示有n个学生,n<100。
此后每行包含一个字符串和两个整数,分别表示学生的学号(字符串长度小于10)和出生月(1<=m<=12)日(1<=d<=31)。
学号、月、日之间用一个空格分隔。

输出

对每组生日相同的学生,输出一行,
其中前两个数字表示月和日,后面跟着所有在当天出生的学生的学号,数字、学号之间都用一个空格分隔。
对所有的输出,要求按日期从前到后的顺序输出。
对生日相同的学号,按输入的顺序输出。

样例输入

5
00508192 3 2
00508153 4 5
00508172 3 2
00508023 4 5
00509122 4 5

样例输出

3 2 00508192 00508172
4 5 00508153 00508023 00509122

import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
 
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        Map<Md, String> map1 = new TreeMap<Md, String>();
        for (int i = 0; i < n; i++) {
            String sno = sc.next();
            int m = sc.nextInt();
            int d = sc.nextInt();
            Md md1 = new Md(m, d);
            if (map1.containsKey(md1)) {
                map1.put(md1, map1.get(md1) + " " + sno);
            } else {
                map1.put(md1, sno);
            }
 
        }
        Set<Md> ks = map1.keySet();
        for (Md k : ks) {
            String v = map1.get(k);
            if (v.contains(" ")) {
                System.out.println(k.m + " " + k.d + " " + v);
            }
        }
    }
}
 
class Md implements Comparable<Md> {
    int m, d;
 
    public Md(int m, int d) {
        this.m = m;
        this.d = d;
    }
 
    @Override
    public int compareTo(Md o) {
        return this.m == o.m ? this.d - o.d : this.m - o.m;
    }
}

45:扩号匹配

描述

判断一组匹配的左右扩号序列中,每一个右扩号与之相匹配成对的左扩号是整个扩号序列的第几个扩号。输出所有判断结果。

输入

输入有两行。
第一行输入一个整数(该整数必定是偶数),该整数表示扩号序列中一共有多少个扩号。
第二行输入用1和2分别代表左右扩号的扩号序列。例如输入序列11211222,表示扩号序列(()(()))。

输出

输出为一行。即挨个输出每个2(右扩号‘)’)与之相匹配的1(左扩号‘(’)在扩号序列中是第几个,用空格格开。

样例输入

4
1212
4
1122
6
112122
8
11211222
20
11211122122121122212

样例输出

1 3
2 1
2 4 1
2 5 4 1
2 6 5 9 4 12 15 14 1 19

提示

输入的扩号总数一定为偶数。输入的12序列必定是匹配的,1和2的个数相等,必为扩号总数的一半。
测试数据有多组,采用while()循环输入。

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			int n = sc.nextInt();
			sc.nextLine();
			String s = sc.nextLine();
			char[] arr = s.toCharArray();
			for (int i = 1; i < arr.length; i++) {
				if (arr[i] == '2') {
					for (int j = i; j >= 0; j--) {
						if (arr[j] == '1') {
							arr[j] = '0';
							System.out.print(j+1 + " ");
							break;
						}
					}
				}
			}
			System.out.println();
		}
	}
}

46:集合合并

描述

已知集合A与集合B,且第个集合内数据是唯一的。求A,B集合合并成新的集合C,要求C集合内的数据也是唯一的。并指出C集合的个数。

输入

三行,第一行分别为集合A,B的个数
第二行为A集合的数据
第三行为B集合的数据

输出

两行
第一行集合C的个数
第二行为C集合的数据

样例输入

4 5
12 34 56 78
34 67 89 34 76

样例输出

7
12 34 56 78 67 89 76

提示

数据小于30000

import java.util.LinkedHashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int A = sc.nextInt(); // 集合A的个数
		int B = sc.nextInt(); // 集合B的个数
		Set<Integer> C = new LinkedHashSet<>();// 新建集合C
		for (int i = 0; i < A + B; i++) {
			C.add(sc.nextInt());
		}
		System.out.println(C.size()); // 集合C的个数
		for (Integer k : C) {
			System.out.print(k + " ");
		}
	}
}

47:字符串排序

描述

先输入你要输入的字符串的个数。然后换行输入该组字符串。每个字符串以回车结束,每个字符串少于一百个字符。如果在输入过程中输入的一个字符串为“stop”,也结束输入。
然后将这输入的该组字符串按每个字符串的长度,由小到大排序,按排序结果输出字符串。

输入

字符串的个数,以及该组字符串。每个字符串以‘\n’结束。如果输入字符串为“stop”,也结束输入.

输出

将输入的所有字符串按长度由小到大排序输出(如果有“stop”,不输出“stop”)。

样例输入

5
sky is grey
cold
very cold
stop
3
it is good enough to be proud of
good
it is quite good

样例输出

cold
very cold
sky is grey
good
it is quite good
it is good enough to be proud of

提示

根据输入的字符串个数来动态分配存储空间(采用new()函数)。每个字符串会少于100个字符。
测试数据有多组,注意使用while()循环输入。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNextInt()) {
			int n = sc.nextInt();
			sc.nextLine();
			List<String> list1 = new ArrayList<>();
			for (int i = 0; i < n; i++) {
				String s = sc.nextLine();
				if (s.equals("stop")) {
					break;
				} else {
					list1.add(s);
				}
			}
			Collections.sort(list1, (a, b) -> a.length() - b.length());
			for (String ss : list1) {
				System.out.println(ss);
			}
		}
	}
}

48:最远距离

描述

给定一组点(x,y),求距离最远的两个点之间的距离。

输入

第一行是点数n(n大于等于2)
接着每一行代表一个点,由两个浮点数x y组成。

输出

输出一行是最远两点之间的距离。
使用printf("%.4f\n", dis)输出距离值并精确到小数点后4位。

样例输入

6
34.0 23.0
28.1 21.6
14.7 17.1
17.0 27.2
34.7 67.1
29.3 65.1

样例输出

53.8516

提示

注意在内部计算时最好使用double类型,但在用scanf读取数据时只能用float类型的变量。

import java.util.Scanner;

public class Main {
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		Point[] p = new Point[n];
		for (int i = 0; i < n; i++) {
			p[i] = new Point(sc.nextDouble(), sc.nextDouble());
		}
		double max = 0;
		for (int i = 0; i < n - 1; i++) {
			for (int j = i + 1; j < n; j++) {
				double t = p[i].dis(p[j]);
				if (t > max) {
					max = t;
				}
			}
		}
		System.out.printf("%.4f\n", max);
	}
}

class Point {
	double x, y;

	public Point(double x, double y) {
		this.x = x;
		this.y = y;
	}

	public double dis(Point p) {
		return Math.sqrt(((this.x - p.x) * (this.x - p.x)) + ((this.y - p.y) * (this.y - p.y)));
	}
}

49:竞赛评分

描述

现举行一次小竞赛,参赛的3支队伍,编号为1,2,3.每支队列轮流回答问题,如果回答正确,加10分;回答错误,扣10分;放弃回答不得分.经过多轮答题后,我们要统计各队的名次和得分.

输入

第一行为回答问题的轮次数n.
其余各行分别为1,2,3号队伍答题的结果,回答正确为right,错误为wrong,放弃为give-up.

输出

按名次输出各队的编号和得分.名次相同的在同一行输出,且编号小者靠前.

样例输入

4
right wrong give-up
right right right
wrong right right
right right right

样例输出

(3,30)
(1,20)(2,20)

import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(); // 回答问题的轮次数n
		Team[] team = new Team[3]; // 3支参赛队伍
		for (int i = 0; i < 3; i++) {
			team[i] = new Team(i + 1, 0);// 初始化队伍编号和分数
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < 3; j++) {
				String answer = sc.next();
				if (answer.equals("right")) {
					team[j].score += 10;
				} else if (answer.equals("wrong")) {
					team[j].score -= 10;
				}
			}
		}
		Arrays.sort(team, (t1, t2) -> t2.score - t1.score);
		for (int i = 1; i <= 3; i++) {
			if (i==3){
				System.out.print("(" + team[i - 1].no + "," + team[i - 1].score + ")");
				break;
			}
			System.out.print("(" + team[i - 1].no + "," + team[i - 1].score + ")");
			if (team[i].score < team[i - 1].score) {
				System.out.println();
			}
		}
	}
}

class Team {
	int no; // 编号
	int score;// 分数

	public Team(int no, int score) {
		super();
		this.no = no;
		this.score = score;
	}
}

50:素数回文数的个数

描述

求11到n之间(包括n),既是素数又是回文数的整数有多少个。

输入

一个大于11小于1000的整数n。

输出

11到n之间的素数回文数个数。

样例输入

23

样例输出

1

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(); // 输入一个大于11小于1000的整数n
		int count = 0;
		for (int i = 11; i <= n; i++) {
			if (sushu(i) && huiwen(i)) {
				count += 1;
			}
		}
		System.out.print(count);
	}

	static Boolean sushu(int a) { // 素数
		for (int i = 2; i < a; i++) {
			if (a % i == 0) {
				return false;
			}
		}
		return true;
	}

	static Boolean huiwen(int a) { // 回文
		String s = a + "";
		for (int i = 0; i < s.length() / 2; i++) {
			if (s.charAt(i) != s.charAt(s.length() - i - 1)) {
				return false;
			}
		}
		return true;
	}
}

51:验证“歌德巴赫猜想”

描述

验证“歌德巴赫猜想”,即:任意一个大于等于6的偶数均可表示成两个素数之和。

输入

输入只有一个正整数x。(x<=2000)

输出

如果x不是“大于等于6的偶数”,则输出一行:
Error!
否则输出这个数的所有分解形式,形式为:
x=y+z
其中x为待验证的数,y和z满足y+z=x,而且y<=z,y和z均是素数。
如果存在多组分解形式,则按照y的升序输出所有的分解,每行一个分解表达式。
注意输出不要有多余的空格。

样例输入

输入样例1:
7
输入样例2:
10
输入样例3:
100

样例输出

输出样例1:
Error!
输出样例2:
10=3+7
10=5+5
输出样例3:
100=3+97
100=11+89
100=17+83
100=29+71
100=41+59
100=47+53

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int x = sc.nextInt(); // 输入只有一个正整数x
		if ((x % 2 == 0) && (x >= 6)) { // x是大于等于6的偶数
			for (int i = 3; i <= x / 2; i++) {
				if (sushu(i) && sushu(x-i)) {
					System.out.println(x + "=" + i + "+" + (x - i));
				}
			}
		} else { // x不是大于等于6的偶数
			System.out.println("Error!");
		}
	}

	static Boolean sushu(int a) { // 素数
		for (int i = 2; i < a; i++) {
			if (a % i == 0) {
				return false;
			}
		}
		return true;
	}
}

52:肿瘤检测

描述

一张CT扫描的灰度图像可以用一个N*N(0 < N <= 100)的矩阵描述,矩阵上的每个点对应一个灰度值(整数),其取值范围是0-255。我们假设给定的图像中有且只有一个肿瘤。在图上监测肿瘤的方法如下:如果某个点对应的灰度值小于等于50,则这个点在肿瘤上,否则不在肿瘤上。我们把在肿瘤上的点的数目加起来,就得到了肿瘤在图上的面积。任何在肿瘤上的点,如果它是图像的边界或者它的上下左右四个相邻点中至少有一个是非肿瘤上的点,则该点称为肿瘤的边界点。肿瘤的边界点的个数称为肿瘤的周长。现在给定一个图像,要求计算其中的肿瘤的面积和周长。

输入

输入第一行包含一个正整数N(0 < N <= 100),表示图像的大小;接下来N行,每行包含图像的一行。图像的一行用N个整数表示(所有整数大于等于0,小于等于255),两个整数之间用一个空格隔开。

输出

输出只有一行,该行包含两个正整数,分别为给定图像中肿瘤的面积和周长,用一个空格分开。

样例输入

6
99 99 99 99 99 99
99 99 99 50 99 99
99 99 49 49 50 51
99 50 20 25 52 99
40 50 99 99 99 99
99 99 99 99 99 99

样例输出

9 8

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt(); // 输入N表示图像的大小
		int[][] a = new int[N][N]; // 矩阵值初始化为0
		int s = 0; // 面积
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				int t = sc.nextInt();
				if (t <= 50) {
					a[i][j] = 1;
					s += 1;
				}
			}
		}
		int c = 0; // 周长
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (a[i][j] == 1) {
					if (i == 0 || j == 0 || j == N - 1 || i == N - 1) {
						c += 1;
					} else if (a[i - 1][j] == 0 || a[i + 1][j] == 0 || a[i][j - 1] == 0 || a[i][j + 1] == 0) {
						c += 1;
					}
				}
			}
		}
		System.out.print(s + " " + c);
	}
}

53:不吉利日期

描述

在国外,每月的13号和每周的星期5都是不吉利的。特别是当13号那天恰好是星期5时,更不吉利。已知某年的一月一日是星期w,并且这一年一定不是闰年,求出这一年所有13号那天是星期5的月份,按从小到大的顺序输出月份数字。(w=1..7)

输入

输入有一行,即一月一日星期几(w)。(1 <= w <= 7)

输出

输出有一到多行,每行一个月份,表示该月的13日是星期五。

样例输入

7

样例输出

1

10

提示

1、3、5、7、8、10、12月各有31天
4、6、9、11月各有30天
2月有28天

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int w = sc.nextInt(); // 输入星期几
		int[] m = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		for (int i = 1; i < 13; i++) {
			if (week(w, day(i)) == 5) {
				System.out.println(i);
			}
		}
	}

	static int day(int a) {
		int d = 13;
		int[] m = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		for (int i = 1; i < a; i++) {
			d += m[i];
		}
		return d;
	}

	static int week(int w, int d) {
		return ((d - 1) % 7 + (w) % 7) % 7;
	}
}

54:数制转换

描述

求任意两个不同进制非负整数的转换(2进制~16进制),所给整数在long所能表达的范围之内。
不同进制的表示符号为(0,1,...,9,a,b,...,f)或者(0,1,...,9,A,B,...,F)。

输入

输入只有一行,包含三个整数a,n,b。a表示其后的n 是a进制整数,b表示欲将a进制整数n转换成b进制整数。
a,b是十进制整数,2 =< a,b <= 16。

输出

输出包含一行,该行有一个整数为转换后的b进制数。输出时字母符号全部用大写表示,即(0,1,...,9,A,B,...,F)。

样例输入

15 Aab3 7

样例输出

210306

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int a = sc.nextInt(); // 输入a
		String n = sc.next(); // 输入a进制整数
		int b = sc.nextInt(); // 输入b
		int t1 = Integer.parseInt(n, a);
		String t2 = Integer.toString(t1, b).toUpperCase();
		System.out.println(t2);
	}
}

55:谁考了第k名

描述

在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第k名学生的学号和成绩。

输入

第一行有两个整数,分别是学生的人数n(1≤n≤100),和求第k名学生的k(1≤k≤n)。
其后有n行数据,每行包括一个学号(整数)和一个成绩(浮点数),中间用一个空格分隔。

输出

输出第k名学生的学号和成绩,中间用空格分隔。(注:请用%g输出成绩)

样例输入

5 3
90788001 67.8
90788002 90.3
90788003 61
90788004 68.4
90788005 73.9

样例输出

90788004 68.4

import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int k = sc.nextInt();
		Student[] student = new Student[n];
		for (int i = 0; i < n; i++) {
			student[i] = new Student(sc.next(), sc.nextDouble());
		}
		Arrays.sort(student);
		System.out.println(student[k - 1].toString());
	}
}

class Student implements Comparable<Student> {
	String sno;
	double score;

	public Student(String sno, double score) {
		super();
		this.sno = sno;
		this.score = score;
	}

	public int compareTo(Student o) {
		return o.score > this.score ? 1 : -1;
	}

	@Override
	public String toString() {
		return sno + " " + score;
	}
}

56:奇数单增序列

描述

给定一个长度为N(不大于500)的正整数序列,请将其中的所有奇数取出,并按升序输出。

输入

共2行:
第1行为 N;
第2行为 N 个正整数,其间用空格间隔。

输出

增序输出的奇数序列,数据之间以逗号间隔。数据保证至少有一个奇数。

样例输入

10
1 3 2 6 5 4 9 8 7 10

样例输出

1,3,5,7,9

import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] arr = new int[n];
		for (int i = 0; i < n; i++) {
			arr[i] = sc.nextInt();
		}
		Arrays.sort(arr);
		String s = "";
		for (int i : arr) {
			if (i % 2 != 0) {
				s = s + i + ",";
			}
		}
		System.out.println(s.substring(0, s.length() - 1));
	}
}

57:整数奇偶排序

描述

给定10个整数的序列,要求对其重新排序。排序要求:

1.奇数在前,偶数在后;

2.奇数按从大到小排序;

3.偶数按从小到大排序。

输入

输入一行,包含10个整数,彼此以一个空格分开,每个整数的范围是大于等于0,小于等于100。

输出

按照要求排序后输出一行,包含排序后的10个整数,数与数之间以一个空格分开。

样例输入

4 7 3 13 11 12 0 47 34 98

样例输出

47 13 11 7 3 0 4 12 34 98

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int[] a = new int[10];
		int i;
		List ji = new ArrayList();
		List ou = new ArrayList();
		for (i = 0; i < 10; i++) {
			a[i] = sc.nextInt();
			if (a[i] % 2 != 0) {
				ji.add(a[i]);
			} else if (a[i] % 2 == 0) {
				ou.add(a[i]);
			}
		}
		Collections.sort(ji);
		for (i = ji.size() - 1; i >= 0; i--) {
			System.out.print(ji.get(i));
			System.out.print(" ");
		}
		Collections.sort(ou);
		for (i = 0; i < ou.size(); i++) {
			System.out.print(ou.get(i));
			System.out.print(" ");
		}
	}
}

58:整数去重

描述

给定含有n个整数的序列,要求对这个序列进行去重操作。所谓去重,是指对这个序列中每个重复出现的数,只保留该数第一次出现的位置,删除其余位置。

输入

输入包含两行:
第一行包含一个正整数n(1 <= n <= 20000),表示第二行序列中数字的个数;
第二行包含n个整数,整数之间以一个空格分开。每个整数大于等于10、小于等于100。

输出

输出只有一行,按照输入的顺序输出其中不重复的数字,整数之间用一个空格分开。

样例输入

5
10 12 93 12 75

样例输出

10 12 93 75

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] a = new int[n];
		boolean[] t = new boolean[n];
		for (int i = 0; i < n; i++) {
			a[i] = sc.nextInt();
			t[i] = true;
		}
		for (int i = 0; i < n; i++) {
			if (t[i] == true) {
				for (int j = i+1; j < n; j++) {
					if (a[i] == a[j]) {
						t[j] = false;
					}
				}
			}
		}
		for (int i = 0; i < n; i++) {
			if (t[i] == true) {
				System.out.print(a[i] + " ");
			}
		}
	}
}

59:接水问题

描述

学校里有一个水房,水房里一共装有 m 个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为 1。

现在有 n 名同学准备接水,他们的初始接水顺序已经确定。将这些同学按接水顺序从 1 到 n 编号,i号同学的接水量为 wi。接水开始时,1 到 m 号同学各占一个水龙头,并同时打开水龙头接水。当其中某名同学 j 完成其接水量要求 wj后,下一名排队等候接水的同学 k 马上接替 j 同学的位置开始接水。这个换人的过程是瞬间完成的,且没有任何水的浪费。即 j 同学第 x 秒结束时完成接水,则 k 同学第 x+1 秒立刻开始接水。 若当前接水人数 n’不足 m,则只有 n’个龙头供水,其它 m-n’个龙头关闭。

现在给出 n 名同学的接水量,按照上述接水规则,问所有同学都接完水需要多少秒。

输入

第 1 行2 个整数 n 和 m,用一个空格隔开,分别表示接水人数和龙头个数。
第 2 行 n 个整数 w1、w2、……、wn,每两个整数之间用一个空格隔开,wi表示 i 号同学的接水量。

1 ≤ n ≤ 10000,1 ≤ m ≤ 100 且 m ≤ n;
1 ≤ wi ≤ 100。

输出

输出只有一行,1 个整数,表示接水所需的总时间。

样例输入

样例 #1:
5 3
4 4 1 2 1

样例 #2:
8 4
23 71 87 32 70 93 80 76

样例输出

样例 #1:
4

样例 #2:
163

提示

输入输出样例1解释:
第 1 秒,3 人接水。第 1秒结束时,1、2、3 号同学每人的已接水量为 1,3 号同学接完水,4 号同学接替 3 号同学开始接水。
第 2 秒,3 人接水。第 2 秒结束时,1、2 号同学每人的已接水量为 2,4 号同学的已接水量为 1。
第 3 秒,3 人接水。第 3 秒结束时,1、2 号同学每人的已接水量为 3,4 号同学的已接水量为 2。4号同学接完水,5 号同学接替 4 号同学开始接水。
第 4 秒,3 人接水。第 4 秒结束时,1、2 号同学每人的已接水量为 4,5 号同学的已接水量为 1。1、2、5 号同学接完水,即所有人完成接水。
总接水时间为 4 秒。

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int[] w = new int[n];
		for (int i = 0; i < n; i++) {
			w[i] = sc.nextInt();
		}
		int time = 0;
		for (int i = m; i < n; i++) {
			int min = 0;
			for (int j = 1; j < m; j++) {
				min = w[min] < w[j] ? min : j;
			}
			w[min]+=w[i];
		}
		for(int i =0;i<n;i++) {
			time = time>w[i]?time:w[i];
		}
		System.out.println(time);
	}
}

60:二进制分类

描述

若将一个正整数化为二进制数,在此二进制数中,我们将数字1的个数多于数字0的个数的这类二进制数称为A类数,否则就称其为B类数。

例如:

(13)10 = (1101)2,其中1的个数为3,0的个数为1,则称此数为A类数;

(10)10 = (1010)2,其中1的个数为2,0的个数也为2,称此数为B类数;

(24)10 = (11000)2,其中1的个数为2,0的个数为3,则称此数为B类数;

程序要求:求出1~1000之中(包括1与1000),全部A、B两类数的个数。

输入

无。

输出

一行,包含两个整数,分别是A类数和B类数的个数,中间用单个空格隔开。

样例输入

(无)

样例输出

(不提供)

//import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		// Scanner sc = new Scanner(System.in);
		int A = 0;
		int B = 0;
		for (int i = 1; i < 1001; i++) {
			if (f(i)) { // 是A类数
				A++;
			} else if (!f(i)) { // 是B类数
				B++;
			}
		}
		System.out.print(A + " " + B);
	}

	static Boolean f(int a) {
		String s = Integer.toBinaryString(a);
		int num_1 = 0;
		int num_0 = 0;
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) == '1') {
				num_1 += 1;
			} else if (s.charAt(i) == '0') {
				num_0 += 1;
			}
		}
		if (num_1 > num_0) { // A类数
			return true;
		}
		return false;
	}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

再见以前说再见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值