PAT Basic Level 1018. 錘子剪刀布 (20) 及最後一個測試點執行超時問題解決

NO IMAGE

1018. 錘子剪刀布 (20)

時間限制
100 ms
記憶體限制
32000 kB
程式碼長度限制
8000 B
判題程式
Standard
作者
CHEN, Yue

大家應該都會玩“錘子剪刀布”的遊戲:兩人同時給出手勢,勝負規則如圖所示:

現給出兩人的交鋒記錄,請統計雙方的勝、平、負次數,並且給出雙方分別出什麼手勢的勝算最大。

輸入格式:

輸入第1行給出正整數N(<=105),即雙方交鋒的次數。隨後N行,每行給出一次交鋒的資訊,即甲、乙雙方同時給出的的手勢。C代表“錘子”、J代表“剪刀”、B代表“布”,第1個字母代表甲方,第2個代表乙方,中間有1個空格。

輸出格式:

輸出第1、2行分別給出甲、乙的勝、平、負次數,數字間以1個空格分隔。第3行給出兩個字母,分別代表甲、乙獲勝次數最多的手勢,中間有1個空格。如果解不唯一,則輸出按字母序最小的解。

輸入樣例:

10
C J
J B
C B
B B
B C
C C
C B
J B
B C
J J

輸出樣例:

5 3 2
2 3 5
B B
我的原始程式碼:提交後得18分,最後一個總是執行超時
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Main_1018 {
public String getOptimal(int[] array,int winByC,int winByJ,int winByB){
        //從小到大排序,冒泡法
        for(int i=0;i<array.length;i  ){
        	for(int j=0;j<array.length-1-i;j  ){
        		if(array[j]>array[j 1]){
        			int temp =array[j];
        			array[j]=array[j 1];
        			array[j 1]=temp;
        		}
        	}
        }
String optimalChoice=null;
if(array[2]>array[1]){
  if(array[2]==winByC){
  optimalChoice="C";
  }
  if(array[2]==winByJ){
  optimalChoice="J";
  }
  if(array[2]==winByB){
  optimalChoice="B";
  }
}
else{//arr[2]=arr[1]           因為arr[2]<=arr[1],排過序了,<不可能
       if(array[2]==array[1]&&array[1]==array[0]){
       	   optimalChoice ="B";
       }
       else{//arr[2]=arr[1] &&array[1] > array[0]
    		   if(array[0]==winByC){//贏的次數最小的錘子,另外兩種贏的次數相同
   			   optimalChoice="B";
   		   }
   		   if(array[0]==winByJ){//贏的次數最小的剪刀,另外兩種贏的次數相同
   			   optimalChoice="B";
   		   }
   		   if(array[0]==winByB){//贏的次數最小的布,另外兩種贏的次數相同
   			   optimalChoice="C";
   		   }
       }
}
return optimalChoice;
}
public static  void main(String[] arg){
Scanner sc =new Scanner(System.in);
int n = Integer.valueOf(sc.nextLine());
int win_jia =0;//即乙輸的次數
int draw_jia=0;//即乙平的次數
int lose_jia=0;//即乙贏的次數
int winByC_jia=0;
int winByJ_jia=0;
int winByB_jia=0;
int winByC_yi=0;
int winByJ_yi=0;
int winByB_yi=0;
char[] arr =null;
for(int i=0 ;i<n ;i  ){
arr=sc.nextLine().toCharArray();
if(arr[0]=='C'&&arr[2]=='J'){
winByC_jia  ;
}
if(arr[0]=='J'&&arr[2]=='B'){
winByJ_jia  ;
}
if(arr[0]=='B'&&arr[2]=='C'){
winByB_jia  ;
}
if(arr[0]==arr[2]){
draw_jia  ;
}
if(arr[2]=='C'&&arr[0]=='J'){
winByC_yi  ;
}
if(arr[2]=='J'&&arr[0]=='B'){
winByJ_yi  ;
}
if(arr[2]=='B'&&arr[0]=='C'){
winByB_yi  ;
}
}
win_jia =winByC_jia winByJ_jia winByB_jia;
lose_jia=winByC_yi winByJ_yi winByB_yi;
Main_1018 test =new Main_1018();
        int[] array1 =new int[3];
        array1[0]=winByC_jia;array1[1]=winByJ_jia;array1[2]=winByB_jia;
      String optimalChoice_jia=test.getOptimal(array1, winByC_jia, winByJ_jia, winByB_jia);
        array1[0]=winByC_yi;array1[1]=winByJ_yi;array1[2]=winByB_yi;
      String optimalChoice_yi=test.getOptimal(array1, winByC_yi, winByJ_yi, winByB_yi);
      System.out.println(win_jia " " draw_jia " " lose_jia);
      System.out.println(lose_jia " " draw_jia " " win_jia);
      System.out.print(optimalChoice_jia " " optimalChoice_yi);
      
}
}
我修改後,提交得20分的程式碼
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main_1018 {
public String getOptimal(int[] array,int winByC,int winByJ,int winByB){
        //從小到大排序,冒泡法
        for(int i=0;i<array.length;i  ){
        	for(int j=0;j<array.length-1-i;j  ){
        		if(array[j]>array[j 1]){
        			int temp =array[j];
        			array[j]=array[j 1];
        			array[j 1]=temp;
        		}
        	}
        }
String optimalChoice=null;
if(array[2]>array[1]){
  if(array[2]==winByC){
  optimalChoice="C";
  }
  if(array[2]==winByJ){
  optimalChoice="J";
  }
  if(array[2]==winByB){
  optimalChoice="B";
  }
}
else{//arr[2]=arr[1]           因為arr[2]<=arr[1],排過序了,<不可能
       if(array[2]==array[1]&&array[1]==array[0]){
       	   optimalChoice ="B";
       }
       else{//arr[2]=arr[1] &&array[1] > array[0]
    		   if(array[0]==winByC){//贏的次數最小的錘子,另外兩種贏的次數相同
   			   optimalChoice="B";
   		   }
   		   if(array[0]==winByJ){//贏的次數最小的剪刀,另外兩種贏的次數相同
   			   optimalChoice="B";
   		   }
   		   if(array[0]==winByB){//贏的次數最小的布,另外兩種贏的次數相同
   			   optimalChoice="C";
   		   }
       }
}
return optimalChoice;
}
public static  void main(String[] arg){
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));  
int n=0;
try {
n = Integer.valueOf(br.readLine());
} catch (NumberFormatException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
int win_jia =0;//即乙輸的次數
int draw_jia=0;//即乙平的次數
int lose_jia=0;//即乙贏的次數
int winByC_jia=0;
int winByJ_jia=0;
int winByB_jia=0;
int winByC_yi=0;
int winByJ_yi=0;
int winByB_yi=0;
char[] arr =null;
for(int i=0 ;i<n ;i  ){
try {
arr=br.readLine().toCharArray();
} catch (IOException e) {
e.printStackTrace();
}
if(arr[0]=='C'&&arr[2]=='J'){
winByC_jia  ;
}
if(arr[0]=='J'&&arr[2]=='B'){
winByJ_jia  ;
}
if(arr[0]=='B'&&arr[2]=='C'){
winByB_jia  ;
}
if(arr[0]==arr[2]){
draw_jia  ;
}
if(arr[2]=='C'&&arr[0]=='J'){
winByC_yi  ;
}
if(arr[2]=='J'&&arr[0]=='B'){
winByJ_yi  ;
}
if(arr[2]=='B'&&arr[0]=='C'){
winByB_yi  ;
}
}
win_jia =winByC_jia winByJ_jia winByB_jia;
lose_jia=winByC_yi winByJ_yi winByB_yi;
Main_1018 test =new Main_1018();
        int[] array1 =new int[3];
        array1[0]=winByC_jia;array1[1]=winByJ_jia;array1[2]=winByB_jia;
      String optimalChoice_jia=test.getOptimal(array1, winByC_jia, winByJ_jia, winByB_jia);
        array1[0]=winByC_yi;array1[1]=winByJ_yi;array1[2]=winByB_yi;
      String optimalChoice_yi=test.getOptimal(array1, winByC_yi, winByJ_yi, winByB_yi);
      System.out.println(win_jia " " draw_jia " " lose_jia);
      System.out.println(lose_jia " " draw_jia " " win_jia);
      System.out.print(optimalChoice_jia " " optimalChoice_yi);
      
}
}
問題在於:
我原來的程式碼中,獲取輸入,使用了Scanner的nextLine()方法
Scanner的nextLine()的API:
Advances this scanner past the current line and returns the input that was skipped. 
This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line. 

Since this method continues to search through the input looking for a line separator, 

it may buffer all of the input searching for the line to skip if no line separators are present.

大意:使Scanner跳過當前行,並返回被跳過的當前輸入行。

返回當前行所剩餘的所有東東,包括換行符,並且下一次讀取的位置被設定到了下一行的beginning

 

可能出現的問題,it may buffer all of the input searching for the line to skip if no line separators are present

修改提交20分的程式碼,我獲取輸入使用了BufferedReader 的 readLine()方法
BufferedReader readLine方法 API:
Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
Throws:
IOException – If an I/O error occurs