1001 卡拉兹猜想:
对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……
我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int m=0;
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while(n!=1) {
if(n%2==0) {
m++;
n=n/2;
}else {
n=(3*n+1)/2;
m++;
}
}
System.out.println(m);
}
}
这是我给的代码但是好像Scanner的载入实在太慢了,耗时248ms,程序运行时间有点长,可以改成bufferReader,而且代码不够模块化。下面是改进的版本。
import java.io.*;
public class Main {
static int m=0;
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String target = bufferedReader.readLine();
method(target);
}
public static void method(String target){
int n=Integer.parseInt(target);
while(n!=1) {
if(n%2==0) {
m++;
n=n/2;
}else {
n=(3*n+1)/2;
m++;
}
}
System.out.println(m);
}
}
耗时148ms
1002 写出这个数:
读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。
import java.io.BufferedReader;
import java.io.InputStreamReader;
class Main {
public static void main(String[] args) throws Exception {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String target = bufferedReader.readLine();
System.out.println(method(target));
}
public static String method(String target) {
int sum = 0;
for (int i = 0 ; i < target.length() ; i ++)
sum += (int)target.charAt(i)-48;
StringBuffer stringBuffer = new StringBuffer();
int digit = getDigit(sum);
for (int i = digit - 1 ; i > 0 ; i --) {
stringBuffer.append(getSplitResult(sum / (int) Math.pow(10, i)) + " ");
sum %= Math.pow(10,i);
}
stringBuffer.append(getSplitResult(sum % 10));
return stringBuffer.toString();
}
public static String getSplitResult(int i) {
switch (i) {
case 0:
return "ling";
case 1:
return "yi";
case 2:
return "er";
case 3:
return "san";
case 4:
return "si";
case 5:
return "wu";
case 6:
return "liu";
case 7:
return "qi";
case 8:
return "ba";
case 9:
return "jiu";
}
return null;
}
public static int getDigit(int target) {
for (int i = 0 ; i < 100 ; i ++) {
if (target / (int) Math.pow(10, i) == 0)
return i;
}
return -1;
}
}
耗时112ms
1003
我要通过!
答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
- 字符串中必须仅有
P
、A
、T
这三种字符,不可以包含其它字符; - 任意形如
xPATx
的字符串都可以获得“答案正确”,其中x
或者是空字符串,或者是仅由字母A
组成的字符串; - 如果
aPbTc
是正确的,那么aPbATca
也是正确的,其中a
、b
、c
均或者是空字符串,或者是仅由字母A
组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
这个问题主要是第三个条件要注意,要递归来判断,一开始不太懂这个题目,后来网上看了大佬的解答。这个题目主要就是递归的应用,当然也可以去找规律。下面是对递归的做法的一点整理。条件一和二比较好理解。如果输入的字符串是这两种类型可以直接判断出来,当输入的字符串为aPbATca这种,其实就是一直拆解到变成前两个模式就可以了。把aPbATca拆成aPbTc 判断其是否是条件一二的模式,如果不是,把aPbTc用aPbATca的模式来表示,继续拆解,拆解到最后拆不出前两种模式就是错误。下面是代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int total = Integer.parseInt(scanner.nextLine());
for (int i = 0; i < total; i++) {
StringBuilder stringBuilder = new StringBuilder(scanner.nextLine());
if(conditionFirst(stringBuilder)){
if(conditionSecond(stringBuilder)){
System.out.println("YES");
}else{
if(conditionThird(stringBuilder)){
System.out.println("YES");
}else{
System.out.println("NO");
}
}
}else{
System.out.println("NO");
}
}
}
private static boolean conditionFirst(StringBuilder stringBuilder){
for (int i = 0; i < stringBuilder.length(); i++) {
char letter = stringBuilder.charAt(i);
if(letter != 'P' && letter != 'A' && letter != 'T'){
return false;
}
}
return true;
}
private static boolean conditionSecond(StringBuilder stringBuilder){
int indexP = stringBuilder.indexOf("PAT");
//can not find PAT
if(indexP == -1){
return false;
}
for (int i = 0; i < indexP; i++) {
if(stringBuilder.charAt(i) != 'A'){
return false;
}
}
for (int i = indexP + 3; i < stringBuilder.length(); i++) {
if(stringBuilder.charAt(i) != 'A'){
return false;
}
}
if(stringBuilder.substring(0, indexP).equals(stringBuilder.substring(indexP + 3))){
return true;
}else {
return false;
}
}
private static boolean conditionThird(StringBuilder stringBuilder){
int indexAT = stringBuilder.indexOf("AT");
if(indexAT == -1){
return false;
}
int indexP = stringBuilder.indexOf("P");
if(indexP == -1){
return false;
}
String a = stringBuilder.substring(0, indexP);
String b = stringBuilder.substring(indexP + 1, indexAT);
String ca = stringBuilder.substring(indexAT + 2, stringBuilder.length());
if(ca.length() < a.length()){
return false;
}
String c = ca.substring(0, ca.length() - a.length());
StringBuilder temp = new StringBuilder(a + "P" + b + "T" + c);
if(conditionFirst(temp)){
if(conditionSecond(temp)){
return true;
}else{
if(conditionThird(temp)){
return true;
}else{
return false;
}
}
}else{
return false;
}
}
}
刚开始看代码空想的时候其实还是没看懂,但是打字梳理的时候打着打着就想明白了,就是不停的递归把字符串进行拆解。