题目:PAT-B 1003.我要通过!(20)
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。得到“答案正确”的条件是:
1.字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;
2.任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
3.如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为PAT写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式:
每个测试输入包含1个测试用例。第1行给出一个自然数n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过100,且不包含空格。
输出格式:
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出YES,否则输出NO。
输入样例:
- 8
- PAT
- PAAT
- AAPATAA
- AAPAATAAAA
- xPATx
- PT
- Whatever
- APAAATAA
输出样例:
- YES
- YES
- YES
- YES
- NO
- NO
- NO
- NO
分析
仔细阅读条件,发现条件之间是有着相互关系的,也就是说条件之间不是独立的。
1.有且必有P,A,T三种字符,不能包含其他字符;
2.形如xPATx的字符串,其中x或是空字符串,或是仅由A组成的字符串;
3.“如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。”
这句话我起初没有理解,后来在参考了别人的代码后,发现这句话其实是让考生找出其中的规律。规律如下:a*b=c。其中a,b,c均为字符串中A的数量。
例如:
PAT —— 对于 aPbTc 来说ac是空,b是A。所以 PAAT 是正确的。同理PAAAAAT中间加多少个A都是正确哒~
APATA —— 对于aPbTc来说,abc都是A。所以 APAATAA 是正确的。再类推一下,那么 APAAATAAA 是正确的。
AAPATAA —— 对于aPbTc来说,a和c是AA,b是A。所以AAPAATAAAA是正确的,再类推一下,AAPAAATAAAAAA 是正确的~
注意:
这三个条件是有嵌套关系的,2、3两个条件是建立在条件1成立的基础之上的,条件3是建立在条件1和2成立的基础之上的。
我在看了样例中输入PT后的结果才发现这一点,因为条件3和条件2是必须同时满足才能算正确,所以样例中输入PT,才会输出“NO”。
实现方法:
1.首先排除掉不符合条件的数据,即出现了PAT以外的字符和P,T出现过两次及以上的数据;
2.再找出P,A,T的下标,根据下标来判断是否满足条件2和条件3,然后根据是否满足条件,输出YES or NO即可。
代码如下:
public class GradeB1003 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine();
for (int i = 0; i < n; i++) {
String s1 = sc.nextLine();
String s2 = s1;
if (s2.contains("P") && s2.contains("A") && s2.contains("T")) {
s2 = s2.replace("P", "");
s2 = s2.replace("A", "");
s2 = s2.replace("T", "");
if (s2.isEmpty()) {
int p = s1.indexOf("P");
int t = s1.indexOf("T");
int l = s1.length();
int a = p;
int b = t - p - 1;
int c = l - t - 1;
if (a * b == c) {
System.out.println("YES");
} else {
System.out.println("NO");
}
} else {
System.out.println("NO");
}
} else {
System.out.println("NO");
}
}
}
}
题目:PAT-B 1004.成绩排名(20)
读入n名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。
输入格式:每个测试输入包含1个测试用例,格式为
第1行:正整数n
第2行:第1个学生的姓名 学号 成绩
第3行:第2个学生的姓名 学号 成绩
… … …
第n+1行:第n个学生的姓名 学号 成绩
其中姓名和学号均为不超过10个字符的字符串,成绩为0到100之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。
输出格式:
对每个测试用例输出2行,第1行是成绩最高学生的姓名和学号,第2行是成绩最低学生的姓名和学号,字符串间有1空格。
输入样例:
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95
输出样例:
Mike CS991301
Joe Math990112
分析
Java实现方法是:
先将所有输入全部存到姓名和学号数组里,然后找出最高成绩的索引和最低成绩的索引,在输入完成后,根据索引输出结果。
代码如下:
public class GradeB1004 {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String s = bufferedReader.readLine();
int n = Integer.valueOf(s);
if (n < 1) {
System.exit(0);//正常退出程序
}
String[] sname = new String[n];//姓名
String[] sno = new String[n];//学号
int[] grade = new int[n];//成绩
int min_index = 100;//初始最小索引
int min = 100;//初始最小
int max_index = 0;//初始最大索引
int max = 0;//初始最大
for (int i = 0; i < n; i++) {
String ss = bufferedReader.readLine();
String[] arraySs = ss.split(" ");
if (arraySs[0].length() <1 || arraySs[0].length() > 10 || arraySs[1].length() < 1 || arraySs[1].length() > 10) {
System.exit(0);
}
sname[i] = arraySs[0];
sno[i] = arraySs[1];
grade[i] = Integer.valueOf(arraySs[2]);
if (grade[i] < 0 || grade[i] > 100) {
System.exit(0);
}
}
for (int j = 0; j < n; j++) {
if (grade[j] > max) {
max = grade[j];
max_index = j;
}
if (grade[j] < min) {
min = grade[j];
min_index = j;
}
}
System.out.println(sname[max_index] + " " + sno[max_index]);
System.out.println(sname[min_index] + " " + sno[min_index]);
}
}