博弈论6
Game
Sample Input
3 4 1 3 1 2 3 2 1
Sample Output
Caspar分析:
大致题意:
就是我们小时候玩的“接火车”,每人轮流拿一张牌出来,形成新的序列,如果这个序列里有和你的牌号一样的牌,你就可以将那张牌到你的牌之间的所有牌取出,放在你自己的序列里。例如:新序列为1,2,3,5,8,4,而如果此时你拿出的是一张3的话,你就可以将3,5,8,4,3取出,放入你自己的序列里,那么新序列就是1,2了。如果轮到一方,并且这方自己的序列没有牌了,那他(她)就算输了
思路:
其实这道题只需模拟一下整个过程就行了。由于新序列始终是从尾部取,所以用一个数组就行了,并记下尾部的位置;而由于博弈的双方要轮流的从头取牌,还会在尾部加牌,那用一个环形队列也就行了,环形队列节约并利用空间
代码如下:
1 # include<stdio.h> 2 # include<malloc.h> 3 #define MaxSize 400//由题意,所有的元素个数永远不会超过400 4 typedef int ElemType; 5 typedef struct node 6 { 7 ElemType data[MaxSize]; 8 int front,rear; 9 }SqQueue; 10 void InitQueue(SqQueue *&q) 11 { 12 q=(SqQueue *)malloc(sizeof(SqQueue)); 13 q->front=q->rear=0; 14 } 15 int EmptyQueue(SqQueue *q) 16 { 17 return (q->front==q->rear); 18 } 19 void InsertQueue(SqQueue *&q,ElemType e) 20 { 21 q->rear=(q->rear+1)%MaxSize; 22 q->data[q->rear]=e; 23 } 24 int main() 25 { 26 SqQueue *boy,*girl; 27 int dp[MaxSize+2]; 28 int numb,numg; 29 int en,i,j,now; 30 while((scanf("%d %d",&numb,&numg))!=EOF) 31 { 32 InitQueue(boy); 33 InitQueue(girl); 34 for(i=1;i<=numb;i++) 35 scanf("%d",&boy->data[i]); 36 boy->rear=numb; 37 for(i=1;i<=numg;i++) 38 scanf("%d",&girl->data[i]); 39 girl->rear=numg; 40 now=1;//记录轮到哪方出牌 41 en=0; 42 while(1) 43 { 44 if(now==1) 45 { 46 if(!EmptyQueue(boy)) 47 { 48 boy->front=(boy->front+1)%MaxSize; 49 dp[en++]=boy->data[boy->front]; 50 now=2; 51 } 52 else 53 { 54 printf("Rapsac\n");//输出胜者 55 break; 56 } 57 } 58 else if(now==2) 59 { 60 if(!EmptyQueue(girl)) 61 { 62 girl->front=(girl->front+1)%MaxSize; 63 dp[en++]=girl->data[girl->front]; 64 now=1; 65 } 66 else 67 { 68 printf("Caspar\n"); 69 break; 70 } 71 } 72 for(i=en-2;i>=0;i--) 73 { 74 if(dp[i]==dp[en-1]) 75 { 76 if(now==2) 77 { 78 for(j=i;j<=en-1;j++) 79 { 80 InsertQueue(boy,dp[j]); 81 } 82 } 83 else if(now==1) 84 { 85 for(j=i;j<=en-1;j++) 86 { 87 InsertQueue(girl,dp[j]); 88 } 89 } 90 en=i;//取出牌后,尾标记也要更新 91 break; 92 } 93 } 94 } 95 } 96 return 0; 97 }