【Java】练习题(6)
51:验证“歌德巴赫猜想”
总时间限制: 1000ms 内存限制: 65536kB
描述
验证“歌德巴赫猜想”,即:任意一个大于等于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 n = sc.nextInt();
if (n % 2 == 0 && n >= 6) {
for (int i = 3; i <= n / 2; i++) {
if (sushu(i) & sushu(n - i)) {
System.out.println(n + "=" + i + "+" + (n - i));
}
}
} else {
System.out.println("Error!");
}
}
static boolean sushu(int a) {
for (int i = 2; i <= Math.sqrt(a); i++) {
if (a % i == 0) {
return false;
}
}
return true;
}
}
52:肿瘤检测
总时间限制: 1000ms 内存限制: 65536kB
描述
一张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();
int[][] a = new int[n][n];
int sum = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int t = sc.nextInt();
if (t <= 50) {
sum++;
a[i][j] = 1;
}
}
}
int sum1 = 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 || i == n - 1 || j == n - 1) {
sum1++;
} else if (a[i][j - 1] == 0 || a[i][j + 1] == 0 || a[i - 1][j] == 0 || a[i + 1][j] == 0) {
sum1++;
}
}
}
}
System.out.println(sum + " " + sum1);
}
}
53:不吉利日期
总时间限制: 1000ms 内存限制: 65536kB
描述
在国外,每月的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 a = sc.nextInt();
for (int i = 1; i < 13; i++) {
if (week(a, days(i)) == 5) {
System.out.println(i);
}
}
}
static int days(int m) {
int[] a = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int n = 13;
for (int i = 1; i < m; i++) {
n += a[i];
}
return n;
}
static int week(int a, int n) {
return (n - 1 + a - 1) % 7 + 1;
}
}
54:数制转换
总时间限制: 1000ms 内存限制: 65536kB
描述
求任意两个不同进制非负整数的转换(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();
String b=sc.next();
int c=sc.nextInt();
int t=Integer.parseInt(b,a);
System.out.println(Integer.toString(t,c).toUpperCase());
}
}
55:谁考了第k名
总时间限制: 1000ms 内存限制: 65536kB
描述
在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第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();
St[] sts=new St[n];
for (int i = 0; i < n; i++) {
sts[i]=new St(sc.next(),sc.nextDouble());
}
Arrays.sort(sts);
System.out.println(sts[k-1].sno+" "+sts[k-1].score);
}
}
class St implements Comparable<St>{
String sno;
double score;
public St(String sno, double score) {
this.sno = sno;
this.score = score;
}
@Override
public int compareTo(St o) {
return o.score>this.score?1:-1;
}
}
56:奇数单增序列
总时间限制: 1000ms 内存限制: 65536kB
描述
给定一个长度为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[] b = new int[n];
int k = 0;
for (int i = 0; i < n; i++) {
int t = sc.nextInt();
if (t % 2 == 1) {
b[k++] = t;
}
}
if (k > 0) {
Arrays.sort(b, 0, k);
for (int i = 0; i < k - 1; i++) {
System.out.print(b[i] + ",");
}
System.out.println(b[k - 1]);
}
}
}
57:整数奇偶排序
总时间限制: 1000ms 内存限制: 65536kB
描述
给定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);
List<Integer> a1 = new ArrayList<Integer>();
List<Integer> a2 = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
int t = sc.nextInt();
if (t % 2 == 1) {
a1.add(t);
} else {
a2.add(t);
}
}
Collections.sort(a1, (x, y) -> y - x);
Collections.sort(a2);
for (Integer i : a1) {
System.out.print(i + " ");
}
for (Integer i : a2) {
System.out.print(i + " ");
}
}
}
58:整数去重
总时间限制: 1000ms 内存限制: 65536kB
描述
给定含有n个整数的序列,要求对这个序列进行去重操作。所谓去重,是指对这个序列中每个重复出现的数,只保留该数第一次出现的位置,删除其余位置。
输入
输入包含两行:
第一行包含一个正整数n(1 <= n <= 20000),表示第二行序列中数字的个数;
第二行包含n个整数,整数之间以一个空格分开。每个整数大于等于10、小于等于100。
输出
输出只有一行,按照输入的顺序输出其中不重复的数字,整数之间用一个空格分开。
样例输入
5
10 12 93 12 75
样例输出
10 12 93 75
代码
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 n = sc.nextInt();
Set<Integer> set1 = new LinkedHashSet<>();
for (int i = 0; i < n; i++) {
set1.add(sc.nextInt());
}
for (Integer k : set1) {
System.out.print(k + " ");
}
}
}
59:接水问题
总时间限制: 1000ms 内存限制: 65536kB
描述
学校里有一个水房,水房里一共装有 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 m = sc.nextInt();
int n = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
for (int i = 0; i < m - n; i++) {
int minpos = minpos(a);
a[minpos] += sc.nextInt();
}
System.out.println(max(a));
}
static int minpos(int[] a) {
int min = 0;
for (int i = 1; i < a.length; i++) {
if (a[i] < a[min]) {
min = i;
}
}
return min;
}
static int max(int[] a) {
int max = a[0];
for (int i = 1; i < a.length; i++) {
if (a[i] > max) {
max = a[i];
}
}
return max;
}
}
60:二进制分类
总时间限制: 1000ms 内存限制: 65536kB
描述
若将一个正整数化为二进制数,在此二进制数中,我们将数字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类数的个数,中间用单个空格隔开。
样例输入
(无)
样例输出
(不提供)
代码
public class Main {
public static void main(String[] args) {
int a=0,b=0;
for (int i = 1; i < 1001; i++) {
String s = Integer.toString(i, 2);
if (isA(s)) {
a++;
}
else{
b++;
}
}
System.out.println(a+" "+b);
}
static boolean isA(String s){
int a1=0,a0=0;
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='1'){
a1++;
} else if (s.charAt(i) == '0') {
a0++;
}
}
return a1>a0;
}
}