1. 程式人生 > >CCF往年真題:遊戲

CCF往年真題:遊戲

問題描述  有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,請問最後獲勝的小朋友編號為多少?輸入格式  輸入一行,包括兩個整數nk,意義如題目所述。輸出格式  輸出一行,包含一個整數,表示獲勝的小朋友編號。樣例輸入5 2樣例輸出3樣例輸入7 3樣例輸出4資料規模和約定  對於所有評測用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 9。

-----------------------------------------------分割線------------------------------------------------------

解題思路:

    建一個student類,有下一個節點和上一個節點地址(因為需要迴圈,所以下一個節點和上一個節點地址都要有),轉換成一個迴圈連結串列模型。再根據題目,進行邊刪除節點邊迴圈前進操作。

程式碼:

import java.util.Scanner;

class student{
	
	int no;
	int reportNum;
	student Next;
	student Pre;
	
	public student() {
		
	}
	
	public void setNo(int no) {
		this.no=no;
	}
	public void setreportNum(int reportNum) {
		this.reportNum=reportNum;
	}
	public int getno() {
		return no;
	}
	public student getPre() {
		return Pre;
	}
	public student getNext() {
		return Next;
	}
}

public class Main {
	
	private static student st;
																																					
	public static void init(int n) {
		
		st=new student();
		student first=st;
		first.setNo(1);
		for(int i=2;i<=n;i++) {
			student s=new student();
			s.no=i;
			first.Next=s;
			s.Pre=first;
			first=s;
		}
		
		first.Next=st;
		st.Pre=first;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		Scanner input=new Scanner(System.in);
		
		//學生數量
		int n=input.nextInt();
		//k值
		int k=input.nextInt();
		
		input.close();
		init(n);
		
		int initnum=1;
		

		
		while(st.Next!=st) {
			

			st.setreportNum(initnum);
			
			if((initnum%10==k)||(initnum%k)==0) {
				
				student pre=st.getPre();
				student next=st.getNext();
				st=next;
				pre.Next=next;
				next.Pre=pre;
			}else {
				st=st.Next;
			}

			initnum++;
		}
		
		System.out.println(st.getno());
	}

}