算法描述
取數游戲:A與B玩取數游戲,隨機產生的2n個整數排成一列,只顯示兩端的整數,只有當A或B取完數會顯示下一個數或者是前一個數(若是取末尾的數)
A的取數策略:采用貪心策略,每次取數取兩個數中最大的那個數
B的取數策略:當兩個數相差較大,取大的那個數,若相差為1,則在這兩個數中隨意取一個數
模擬A與B的取數過程
算法思路
-
隨機產生數值,我們使用Java中的Math.random()方法即可
-
為了方便取數,將隨機產生的2n個整數放在鏈表中,鏈表中有方法可以取出第一個數和最后一個數
getFirst()
返回第一個元素的數值,不將該元素移出鏈表removeFirst()
將第一個元素鏈表鏈表,返回該元素的數值getLast()
返回最后一個元素的數值,不將該元素移出鏈表removeLast()
將最后一個元素移出鏈表,返回該元素的數值 -
設置一個布爾變量
flag
,flag=true
輪到A取數flag=false
輪到B取數 -
分別用兩個一維數組存放A與B的取數
-
A取數采用貪心策略,我們使用get方法,獲得一個數和最后一個數,取大數存放在A數組中
-
B取數有兩個選擇,相差較大(也就是相差大於1),我們就取大數(這里我們在實際當中需要采用
絕對值
);若是等於1,則隨意取,
我們可以使用隨機數的方法,若是隨機數大於0.5,則取第一個數,否則取末尾那個數
如果是A先取數的話,B到最后會出現只剩下一個數的情況,這個時候B沒有選擇,只能取這個數
-
判斷輸贏的話,只需要比較A數組的總和與B數組的總和即可判斷出輸贏
算法實現
Scanner scaner = new Scanner(System.in);
int n = scaner.nextInt();
scaner.close();
LinkedList<Integer> list = new LinkedList<Integer>();
int[] A = new int[n];//存放A所取的數值
int[] B = new int[n];//存放B所取的數值
for(int i=0;i<2*n;i++){
int temp=(int)(Math.random() * 100) ;//0到100的隨機數
list.add(temp);//存入鏈表中
}
boolean flag = true;//A先取數
int count = 0;
//當B數組的最后一個不為0的時候(即是B拿到了最后一個數的時候),退出while
while(count<n){
if(flag){
if(list.getFirst()>list.getLast()){
A[count] = list.removeFirst();
}else{
A[count]=list.removeLast();
}
System.out.println("A取"+A[count]);
flag=false; //改變flag,輪到B取數
}else{
if(list.getFirst()==list.getLast()){//當還剩下一個數的時候,B只能取當前那個數
B[count]=list.removeFirst();
}else if(list.getFirst()-list.getLast()>1){
B[count] = list.removeFirst();//選擇最大的那個數
}else if(Math.abs(list.getFirst()-list.getLast())==1){
//B隨機選擇
if(Math.random()>0.5){
B[count]=list.removeLast();
}else{
B[count]=list.removeFirst();
}
}else{
B[count]=list.removeLast();//第一個數比末尾的數要小,因為上述條件已經排除了等於1的情況,所以末尾的數一定是與第一個數相差較大
}
System.out.println("B取"+B[count]);
count++;
flag = true;//輪到A取數
}
}
int a=A[0],b=B[0];
//判斷輸贏
for(int i=1;i<A.length;i++){
a = a+A[i];
b = b+B[i];
}
if(a>b){
System.out.println("A獲勝了");
}else{
System.out.println("B獲勝了");
}