B.三元组
题目:
给定一个长度为 n 的数列 a,对于一个有序整数三元组 (i, j, k),若其满足 1≤i≤j≤k≤n 并且 ai +aj = ak ,则我们称这个三元组是「传智的」。
现在请你计算,有多少有序整数三元组是传智的。
输入格式:
输入的第一行是一个整数 T,表示数据组数。
对于每组数据:
第一行是一个整数,表示数列的长度 n。
第二行有 n 个整数,第 i 个整数表示 ai。
输出格式:
对于每组数据,输出一行一个整数表示答案。
规模:
对于全部测试点,保证 1001≤T≤100,1≤n,a i≤100,且各个测试点的 n 之和不超过 100,即∑n≤100。
思路:
注意这个三元组前面两个数是可以为0,并且是可以重复的。然后我们从前往后去匹配。注意一下这道题的三元组是有序的,给出的样例也是有序的,以后碰到这样的问题应该考虑要排下序。
代码:
点击查看代码
import java.util.Scanner;
public class MainB {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] b = new int[n];
for(int k = 0;k<n;k++) {
int m = scanner.nextInt();
int[] arr = new int[m+1];
int count = 0;
for(int i = 1;i <= m;i++) {
arr[i] = scanner.nextInt();
}
for(int i = 1;i <= m;i++) {
for(int j = i;j <= m;j++) {
for(int x = j;x <= m;x++) {
if(arr[i]+arr[j]==arr[x]) {
count++;
}
}
}
}
b[k] = count;
}
for(int i = 0;i < n;i++) {
System.out.println(b[i]);
}
}
}
C.单位转换
题目:
我们知道计算机的大小单位有 B, KB, MB 等,现在请你编写一个计算器进行大小单位换算。
提示,1 GB = 2^{10}MB = 2^{20}KB = 2^{30}B。
输入格式
输入一个字符串,由一个 0 到 1023 之间的整数,一个单位名称(大写字母),一个等于号和问号,以及第二个单位名称。
单位只有可能是 GB,MB,KB,B 之间的一个。
输出格式
输出一个数字,精确到小数点后 6 位。
思路:
这道题我最开始找字符串里面的单位的时候总想着字符串从后往前是固定的格式,忘记了最小单位 ' B ' 的这种情况。
后面我用了另一种方法:使用ASCII码中的大写字母段来识别两个单位,然后再用数字段来识别前面的数字。
最后将所有情况列出来匹配了计算。
代码:
点击查看代码
import java.util.Scanner;
public class MainC {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
String Preu="",Posu="",prenum="";
float num1=0f,num2=0f;
int flag = 0;
for(int i = 0;i <str.length();i++) {
if(str.charAt(i)>=65&&str.charAt(i)<=90) {
Preu += str.charAt(i);
if(str.charAt(i+1)=='=') {
flag = i;
break;
}
}
}
for(int i = flag+1;i < str.length();i++) {
if(str.charAt(i)>=65&&str.charAt(i)<=90) {
Posu += str.charAt(i);
}
}
for(int i = 0;i < str.length()/2;i++) {
if(str.charAt(i)>=48&&str.charAt(i)<=57) {
prenum += str.charAt(i);
}
}
num1 = Float.parseFloat(prenum);
if(Preu.equals("GB")) {
if(Posu.equals("MB")) {
num2 = (float) (num1*Math.pow(2, 10));
}else if(Posu.equals("KB")) {
num2 = (float) (num1*Math.pow(2, 20));
}else if(Posu.equals("B")) {
num2 = (float) (num1*Math.pow(2, 30));
}else {
num2 = num1;
}
System.out.printf("%.6f",num2);
}else if(Preu.equals("MB")) {
if(Posu.equals("GB")) {
num2 = (float) (num1/Math.pow(2, 10));
}else if(Posu.equals("KB")) {
num2 = (float) (num1*Math.pow(2, 10));
}else if(Posu.equals("B")) {
num2 = (float) (num1*Math.pow(2, 20));
}else {
num2 = num1;
}
System.out.printf("%.6f",num2);
}else if(Preu.equals("KB")) {
if(Posu.equals("GB")) {
num2 = (float) (num1/Math.pow(2, 20));
}else if(Posu.equals("MB")) {
num2 = (float) (num1/Math.pow(2, 10));
}else if(Posu.equals("B")) {
num2 = (float) (num1*Math.pow(2, 10));
}else {
num2 = num1;
}
System.out.printf("%.6f",num2);
}else if(Preu.equals("B")) {
if(Posu.equals("GB")) {
num2 = (float) (num1/Math.pow(2, 30));
}else if(Posu.equals("MB")) {
num2 = (float) (num1/Math.pow(2, 20));
}else if(Posu.equals("KB")) {
num2 = (float) (num1/Math.pow(2, 10));
}else {
num2 = num1;
}
System.out.printf("%.6f",num2);
}
}
}
D.乘方
题目:
输入a,b,求a^b,并判断
输入格式
输入共一行,两个正整数 a, b。
输出格式
输出共一行,如果 a^b 的值不超过 {10}^9,则输出 a^b 的值,否则输出 -1。
思路:
我们先求一下ab,然后求一下109,然后对比一下,不超过就输出那个结果,超过就输出-1;
109是比231-1小很多,所以我用int接收他们的结果勉强过了,但还是不太保险,下次遇到这样的问题还是考虑用long
代码:
点击查看代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
int result = (int) Math.pow(a, b);
int max = (int) Math.pow(10, 9);
if(result<=max) {
System.out.println(result);
}else {
System.out.println("-1");
}
}
}
E.Grave
题目:
给出墓地和教堂的左下角和右上角坐标,以及墓碑的长宽,求能否放下墓碑
思路:
求出剩余的四块的面积,比较一下长宽。注意长只能对应x轴,宽只能对应y轴。
代码:
点击查看代码
import java.util.Scanner;
public class MainF {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int x1 = scanner.nextInt();
int y1 = scanner.nextInt();
int x2 = scanner.nextInt();
int y2 = scanner.nextInt();
int x3 = scanner.nextInt();
int y3 = scanner.nextInt();
int x4 = scanner.nextInt();
int y4 = scanner.nextInt();
int L = x2-x1;
int H = y2-y1;
int h1 = y2-y4;
int h2 = y3-y1;
int l1 = x3-x1;
int l2 = x2-x4;
int l3 = scanner.nextInt();
int h3 = scanner.nextInt();
if(h1>=h3&&L>=l3) {
System.out.println("Yes");
}else if(h2>=h3&&L>=l3) {
System.out.println("Yes");
}else if(H>=h3&&l1>=l3) {
System.out.println("Yes");
}else if(H>=h3&&l2>=l3) {
System.out.println("Yes");
}else {
System.out.println("No");
}
}
}
F.Bus
题目:
有一个公交车,初始时车上有 n 个人,每停一站,车上会先下去一个人,然后再下去车上剩下的人数的一半的人。已知经过了 k 个站之后,车上没人了。现在,给出 k,求一开始车上的人数 n。
1⩽k⩽30。
思路:
读懂题意列出公式即可。
代码:
点击查看代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n =scanner.nextInt();
int sum = 1;
int[] arr = new int[n];
for(int i = 0;i < n;i++) {
sum = 1;
int k = scanner.nextInt();
while(k!=1) {
k--;
sum = sum*2+1;
}
arr[i]=sum;
}
for(int i = 0;i < n;i++) {
System.out.println(arr[i]);
}
}
}
G.Alarm Clock
题目:
Alice梦见了一个时间,但她只记得了这个时间在电子钟上显现出来的段数,现在给出这个段数,让你反推Alice梦见的时间(若有多个答案,输出任意一个均可)
段数:想必大家都听说过用火柴拼数字的游戏,比如1要用两个火柴,2要用5根火柴,8要用7根火柴等等(如题目图片所示),这里的段数指的就是一个时间的每一个数字,需要火柴数量的和(比如09:30,就要6+6+5+6=23个火柴)。
时间:本题输出的时间仅有小时和分钟,其中小时在0到23之间,分钟在0到59之间
输入一个整数n,n在0到30以内,代表Alice梦见的段数
输出一个字符串,如果有合法的时间满足输入的段数,则输出这个时间(有多个输出任意一个均可),否则输出Impossible
注意时间的前导零
思路:
首先我们将每个数字的段数存放在一个数组里,这里刚好0到9,一共10个数,让下标和里面的段数相对应。然后从00:00开始枚举,看段数加起来是不是等于n就可以了。
代码:
点击查看代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] arr = new int[] {6,2,5,5,4,5,6,3,7,6};
int n = scanner.nextInt();
boolean flag = false;
for(int hh=0;hh < 24;hh++) {
for(int mm = 0;mm < 60;mm++) {
int num1 = hh / 10;
int num2 = hh % 10;
int num3 = mm / 10;
int num4 = mm % 10;
if(arr[num1]+arr[num2]+arr[num3]+arr[num4]==n) {
System.out.println(""+num1+num2+":"+num3+num4);
flag = true;
return;
}
}
}
if(!flag) {
System.out.println("Impossible");
}
}
}
H.采药
题目:
辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”
如果你是辰辰,你能完成这个任务吗?
第一行有 22 个整数 T(1≤T≤1000)和 M(01≤M≤100),用一个空格隔开,T 代表总共能够用来采药的时间,M 代表山洞里的草药的数目。
接下来的 M 行每行包括两个在 1 到 100 之间(包括 1 和 100)的整数,分别表示采摘某株草药的时间和这株草药的价值。
例如:
输入
70 3
71 100
69 1
1 2
输出
3
思路:
这道题是典型的背包问题,我们使用背包问题的模板来做就可以了。
代码:
点击查看代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int time = scanner.nextInt();
int m = scanner.nextInt();
int[] t = new int[m];
int[] value = new int[m];
for(int i = 0;i < m;i++) {
t[i] = scanner.nextInt();
value[i] = scanner.nextInt();
}
int[][] v = new int[m+1][time+1];
for(int i = 0;i < v.length;i++) {
v[i][0] = 0;
}
for(int i = 0;i < v[0].length;i++) {
v[0][i] = 0;
}
for(int i =1;i < v.length;i++) {
for(int j = 1;j < v[0].length;j++) {
if(t[i-1]>j) {
v[i][j] = v[i-1][j];
}else {
v[i][j] = Math.max(v[i-1][j],value[i-1]+v[i-1][j-t[i-1]]);
}
}
}
int max = 0;
for(int i =1;i < v.length;i++) {
for(int j = 1;j < v[0].length;j++) {
if(v[i][j]>max) {
max = v[i][j];
}
}
}
System.out.println(max);
}
}
I.区间内的真素数
题目:
找出正整数 M 和 NN 之间(N 不小于 M)的所有真素数。
真素数的定义:如果一个正整数 P 为素数,且其反序也为素数,那么 P 就为真素数。
例如,11,13 均为真素数,因为 11 的反序还是为 11,13 的反序为 31 也为素数。
输入两个数 M 和 N,空格间隔。按从小到大输出 M 和 N 之间(包括 M 和 N)的真素数,逗号间隔。如果之间没有真素数,则输出 No。
思路:
检验一个数是素数后,用字符串翻转,再检验,如果是则放入到数组中,输出的时候按题目格式输出就可以了。
代码:
点击查看代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
int n = scanner.nextInt();
int[] arr = new int[n-m];
int count = 0;
for(int i = m;i <= n;i++) {
if(isPrime(i)&&isRealPrime(i)) {
arr[count++] = i;
}
}
if(count==0) {
System.out.println("No");
}
for(int i = 0;i < count;i++) {
if(i==count-1) {
System.out.println(arr[i]);
}else {
System.out.print(arr[i]+""+',');
}
}
}
public static boolean isPrime(int n) {
boolean flag = true;
for(int i =2;i <= n/2;i++) {
if(n%i==0) {
flag = false;
return flag;
}
}
return flag;
}
public static boolean isRealPrime(int n) {
String str = n+"";
String str1 = "";
for(int i = str.length()-1;i >= 0;i--) {
str1+=str.charAt(i);
}
int num = Integer.parseInt(str1);
return isPrime(num);
}
}
J.素数回文数的个数
题目:
求 11 到 n 之间(包括 n),既是素数又是回文数的整数有多少个。
输入格式:
一个大于 11 小于 10000 的整数 n。
输出格式:
11 到 n 之间的素数回文数个数。
思路:
判断是否是素数然后再判断是否回文。
代码:
点击查看代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int count = 0;
for(int i = 11;i <= n;i++) {
if(isPrime(i)&&isLegel(i)) {
count++;
}
}
System.out.println(count);
}
public static boolean isPrime(int n){
boolean flag = true;
for(int i =2;i < n/2;i++) {
if(n%i==0) {
flag = false;
return flag;
}
}
return flag;
}
public static boolean isLegel(int n) {
String str = n+"";
int length = str.length();
if(length==2) {
if(str.charAt(0)==str.charAt(1)) {
return true;
}else {
return false;
}
}else if(length==3) {
if(str.charAt(0)==str.charAt(2)) {
return true;
}else {
return false;
}
}else if(length==4) {
if(str.charAt(0)==str.charAt(2)&&str.charAt(1)==str.charAt(3)) {
return true;
}else {
return false;
}
}else if(length==5) {
if(str.charAt(0)==str.charAt(3)&&str.charAt(1)==str.charAt(4)) {
return true;
}else {
return false;
}
}else {
return false;
}
}
}