1001.害死人不偿命的(3n+1)猜想
卡拉兹(Callatz)猜想:
对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……
我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?
输入格式:
每个测试输入包含 1 个测试用例,即给出正整数 n 的值。
输出格式:
输出从 n 计算到 1 需要的步数。
输入样例变化过程如下所示:
第一步(3是奇数):3-->(3*3+1)/2=5
第二步(5是奇数):5-->(5*3+1)/2=8
第三步(8是偶数):8-->(8/2)=4
第四步(4是偶数):4-->(4/2)=2
第五步(2是偶数):2-->(2/1)=1
此题较为简单,只需要弄明白数据的变化规律即可,因此只需要一个简单的循环就可以解决问题!
代码如下所示:
import java.util.Scanner;
public class Main{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
//count用来计数
int count=0;
while(n>1){
if(n%2==0)//n为偶数
n/=2;
else//n为奇数
n=(3*n+1)/2;
count++;
}
System.out.println(count);
}
}
1002.写出这个数
读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。
输入格式:
每个测试输入包含 1 个测试用例,即给出自然数 n 的值。这里保证 n 小于 10
100 。
输出格式:
在一行内输出 n 的各位数字之和的每一位,拼音数字间有 1 空格,但一行中最后一个拼音数字后没有空格。
输入样例到输出结果的变化过程如下:
首先,累加所有的数字和
1+2+3+4+5+6+7+8+9+0+9+8+7+6+5+4+3+2+1+1+2+3+4+5+6+7+8+9=135
百位的是1 对应的拼音是 yi
十位的是3 对应的拼音是 san
个位的是5 对应的拼音是 wu
因此最后按照题目格式的输出为
yi san wu
按照上述思路,具体解决问题的思路如下:
首先我们将用户输出的字符串转换为对应的字符数组,通过遍历字符数组的值来计算其每一位数值的累加和,紧接着建立由0-9的拼音组成的字符串数组,然后将计算的累加和转换为字符串,再次遍历其每一位的数值字符,建立起与拼音数组的关系,最后按照格式输出对应的值即可!
具体代码如下所示:
import java.util.Scanner;
public class Main{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
String line=sc.nextLine();
//将字符串转换为字符数组
char[] chars=line.toCharArray();
//记录每一位数字的和
int sum=0;
for(int i=0;i<chars.length;i++){
sum+=(chars[i]-'0');
}
String[] str={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
String sumStr=Integer.valueOf(sum).toString();
for(int i=0;i<sumStr.length()-1;i++){
System.out.print(str[sumStr.charAt(i)-'0']+" ");
}
//最后一位输出没有空格
System.out.print(str[sumStr.charAt(sumStr.length()-1)-'0']);
}
}
1003.我要通过!
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式:
每个测试输入包含 1 个测试用例。第 1 行给出一个正整数 n (≤10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过 100,且不包含空格。
输出格式:
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出 YES,否则输出 NO。
通过分析题目的要求,可以得出以下结论:
1.字符串中必须有且仅有P,A,T三种字符出现
2.P和T之间A的个数必须大于等于1,没有A就是错误的
3.开头(P之前)的A的个数 * 中间(P和T中间)的A的个数 = 结尾(T之后)的A的个数
4.P和T只能有一个,防止出现类似于PATTTTT这样的情况
分析出以下特征以后,再来解决这个问题就变得更加容易了,具体代码如下所示:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while (n-- > 0) {
String input = sc.next();
if (judge(input)) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
sc.close();
}
//本题必须满足的条件如下:
// 1.字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
// 2.P和T之间不能没有A(A的个数大于等于1,等于0就是错的)
// 3.开头(P之前)的A的个数 * 中间(P和T中间)的A的个数 = 结尾(T之后)的A的个数,
// 4.P和T只能有一个,防止出现类似于PATTTTT这样的情况
private static boolean judge(String str) {
String newStr = str.replace("P", "").replace("A", "").replace("T", "");
if (newStr.isEmpty()) {//判断条件1
int P_index = str.indexOf('P');
int T_index = str.indexOf('T');
if (P_index == T_index - 1) {//判断条件2
return false;
}
if(str.lastIndexOf('P')!=str.indexOf('P'))
return false;
if(str.lastIndexOf('T')!=str.indexOf('T'))
return false;//判断条件4
return P_index * (T_index - P_index - 1) == str.length() - T_index - 1; //判断条件3
}
return false;
}
}
1004.成绩排名
读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。
输入格式:
每个测试输入包含 1 个测试用例,格式为
第 1 行:正整数 n
第 2 行:第 1 个学生的姓名 学号 成绩
第 3 行:第 2 个学生的姓名 学号 成绩
... ... ...
第 n+1 行:第 n 个学生的姓名 学号 成绩
其中姓名和学号均为不超过 10 个字符的字符串,成绩为 0 到 100 之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。
输出格式:
对每个测试用例输出 2 行,第 1 行是成绩最高学生的姓名和学号,第 2 行是成绩最低学生的姓名和学号,字符串间有 1 空格。
这道题目仅仅采用数组就可以解决,当然如果要使用集合更好,因为可以使用集合直接获得排序后的元素索引!这里我使用三个数组,分别为姓名数组,学号数组,成绩数组来存储对应的信息,通过遍历成绩数组来获得最大成绩与最小成绩的下标,按照个数输出对应的值即可!
具体代码如下所示:
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
String[] names=new String[n];
String[] snos=new String[n];
int[] scores=new int[n];
for(int i=0;i<n;i++){
names[i]=sc.next();
snos[i]=sc.next();
scores[i]=Integer.parseInt(sc.next());
}
int minIndex=0,minValue=scores[0];
int maxIndex=0,maxValue=scores[0];
for(int i=1;i<n;i++){
if(scores[i]<minValue){
minValue=scores[i];
minIndex=i;
}
if(scores[i]>maxValue){
maxValue=scores[i];
maxIndex=i;
}
}
System.out.println(names[maxIndex]+" "+snos[maxIndex]);
System.out.println(names[minIndex]+" "+snos[minIndex]);
}
}
这里需要注意的是,如果nextLine()前面有nextInt(),nextLine()将不再被执行,但如果nextLine()在nextInt()前面,nextLine()仍将被执行。大伙可以自己测试一下,所以我这边在nextInt()之后仅仅使用了next()方法!