CCF 2017_12月考試第2題解析

遊戲

 

有n個小朋友圍成一圈玩遊戲,小朋友從1至n編號,2號小朋友坐在1號小朋友的順時針方向,3號小朋友坐在2號小朋友的順時針方向,……,1號小朋友坐在n號小朋友的順時針方向。
  遊戲開始,從1號小朋友開始順時針報數,接下來每個小朋友的報數是上一個小朋友報的數加1。若一個小朋友報的數爲k的倍數或其末位數(即數的個位)爲k,則該小朋友被淘汰出局,不再參加以後的報數。當遊戲中只剩下一個小朋友時,該小朋友獲勝。
  例如,當n=5, k=2時:
  1號小朋友報數1;
  2號小朋友報數2淘汰;
  3號小朋友報數3;
  4號小朋友報數4淘汰;
  5號小朋友報數5;
  1號小朋友報數6淘汰;
  3號小朋友報數7;
  5號小朋友報數8淘汰;
  3號小朋友獲勝。

  給定n和k,請問最後獲勝的小朋友編號爲多少?

  • 思路:用兩個數組,一個記錄學生編號,一個記錄學生是否被淘汰。
    用 while循環內嵌 for循環,讓i=1爲 小朋友喊得序號,然後 當只剩一個小朋友時,跳出循環。

package one;

import java.util.Scanner;

/**@author : fjl2401 創建時間:2018年2月5日 下午5:11:00
 * 小朋友玩遊戲
 * 
 *  */
public class T_2017_12_2 {
public static void main(String[] args) {
Scanner in =new Scanner(System.in);
String a=in.nextLine();
int n= Integer.parseInt(a.split(" ")[0]);
int k= Integer.parseInt(a.split(" ")[1]);
//生成k個小孩 帶着自己的編號
int Friend[]=new int [n];
boolean flag[]=new boolean[n];
for (int i = 1; i <=n; i++) {
Friend[i-1]=i;
flag[i-1]=true;
}
int i=1;
int sum=0;
//do
while(true) {
for (int j = 0; j < Friend.length; j++) {
    if(flag[j]==true)
    {
    if (i%k==0||i%10==k) {
        flag[j]=false;
     sum++; 
    }
    i++;
    }
}
if(sum==n-1)
break;
}
//out
for (int j = 0; j < Friend.length; j++) {
    if (flag[j]==true) {
        System.out.println(Friend[j]);
    }
}
}
}
  • 代碼很簡明,但在提交時報超時的錯誤,只給了90分。應該是每次循環中,都要把數據遍歷一遍,時間複雜度上不是很好。
  • 想用一個list來解決這個問題,但java的list是每次刪除元素後,list元素的index就會發生變化。會出現錯誤。
  • 最終有了第二版代碼: 用一個queue隊列來實現。還是在循環中,每次移出一個元素,如果這時候 不滿足i%k==0||i%10==k 情況,就把他加在隊列尾部,如果滿足淘汰的情況,就繼續。 知道隊列的長度爲1時,循環停止。
  • 結合題目,第二種也是滿足題目的實際情況的,每個人報完一個數,他就變成了當前情況下最後一個報數的人,所以在實現中把他移到了隊列尾部。
package t2017_9;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
/**@author : fjl2401 創建時間:2018年2月6日 下午11:55:34   */
public class Main {
        public static void main(String[] args) {
        Scanner in =new Scanner(System.in);
        String a=in.nextLine();
        int n= Integer.parseInt(a.split(" ")[0]);
        int k= Integer.parseInt(a.split(" ")[1]);
in.close();     
        //生成k個小孩 帶着自己的編號
Queue<Integer>alist=new LinkedList<>();
for (int i = 1; i <=n; i++) {
alist.add(i);
}
int i=1;
        while(alist.size()>1) {
   int c=alist.poll();
            if (i%k!=0&&i%10!=k) {
             alist.add(c);
            }
            i++;
        }
        System.out.println(alist.poll());
        }
        }

第二種代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章