PAT A1056 2019.07.14 【水题】

该博客介绍了PAT编程竞赛中的一道题目——Mice and Rice,讨论了如何根据程序员的代码控制鼠标在给定地图上的行动以获取最高分数。文章重点在于理解比赛规则,包括随机确定的比赛顺序、分组比赛直至决出最终胜者的过程。博主提供了输入输出规格,并强调理解输入的第三行的重要性。解决方案中提到了使用队列数据结构来模拟比赛过程,通过队头入队和队头队尾交换实现比赛轮转,以此来计算每个程序员的排名。
摘要由CSDN通过智能技术生成

1056 Mice and Rice (25 分)

Mice and Rice is the name of a programming contest in which each programmer must write a piece of code to control the movements of a mouse in a given map. The goal of each mouse is to eat as much rice as possible in order to become a FatMouse.

First the playing order is randomly decided for N​P​​ programmers. Then every N​G​​ programmers are grouped in a match. The fattest mouse in a group wins and enters the next turn. All the losers in this turn are ranked the same. Every N​G​​ winners are then grouped in the next match until a final winner is determined.

For the sake of simplicity, assume that the weight of each mouse is fixed once the programmer submits his/her code. Given the weights of all the mice and the initial playing order, you are supposed to output the ranks for the programmers.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers: N​P​​ and N​G​​ (≤1000), the number of programmers and the maximum number of mice in a group, respectively. If there are less than N​G​​ mice at the end of the player's list, then all the mice left will be put into the last group. The second line contains N​P​​ distinct non-negative numbers W​i​​ (i=0,⋯,N​P​​−1) where each W​i​​ is the weight of the i-th mouse respectively. The third line gives the initial playing order which is a permutation of 0,⋯,N​P​​−1 (assume that the programmers are numbered from 0 to N​P​​−1). All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the final ranks in a line. The i-th number is the rank of the i-th programmer, and all the numbers must be separated by a space, with no extra space at the end of the line.

Sample Input:

11 3
25 18 0 46 37 3 19 22 57 56 10
6 0 8 7 10 5 9 1 4 2 3

Sample Output:

5 5 5 2 5 5 5 3 1 3 5

 

思路分析

最重要的是读懂题目,难点是明白输入的第三行代表什么。

用结构体会让自己的思路更加清晰,此题核心考点在于用队列出队来达到三个属性比大小,之后再次入队

因为出队3个才入队一个,所以可以直接在固定长度队列的队头入队

一轮比赛之后,将队头队尾相互交换,即可得到新队,然后继续进行下一轮比赛

 

#include<cstdio>
#include<iostream>
#define MAX 1010
#define WIN 9898
#define FAL 8989
#define NUL 9999 

typedef struct {
	int weight;
	int inputOrder;
	int cycle;//轮次 
	int outcome; //结果 
	int rank;//最后输出的排序 
} MICE;
MICE mice[MAX];

int que[MAX];
int front=-1;//存放当前轮次 
int rear=-1; 
int front1=-1;//存放下一轮次(当前轮次赢的老鼠) 
int rear1=-1; 
    
int main()
{	
   //[无误]输入模块 
   int np=0,ng=0;
   scanf("%d %d",&np,&ng);//老鼠的数量 
   for(int i=0;i<np;i++)//输入老鼠的重量 
   {
   	scanf("%d",&mice[i].weight);
   }

    for(int temp=0,i=0;i<np;i++)//输入老鼠的进场次序 
   {
   	scanf("%d",&temp);
   	que[++rear]=temp;//入场顺序入队 
   	mice[temp].inputOrder=i;
   }
   
   //[无误]处理模块
   //首先轮次=1 cycle=1 
   int cycle = 1; 
   for(int i=0;i<np;i++)
   {
   	mice[i].cycle=1;//所有的老鼠都要经过第一轮
   	mice[i].outcome=FAL;//目前结果全部为FAL 
	mice[i].rank=NUL;//目前的次序全部为NULL
   } 
   
   
   
   int max=0;
   int temp=0;//控制存入最大值 
   while(front!=rear)//当队非空 
   {
   	   for(int i=0;i<=rear;i++)
	   {
	   	  //每三个一组 
		  //找出最大值(记录轮次结果),最大值入队 front1 rear1 
		  if(temp%ng == 0)//每ng个中的第一个初始化为最大 
		  {
		  	max = que[++front];//先赋值
		  	//mice[max].cycle=cycle;
		  	//mice[max].outcome=WIN;
			que[front]=0;//再出队 
			temp++;//出队1个 temp++ 
		  }
		  else
		  {
		  	++front; 
		  	if(mice[que[front]].weight>mice[max].weight) 
		  	{
		  		//mice[max].outcome=FAL;
		  		max = que[front];//赋值 
		  		//mice[max].cycle=cycle;
		  	    //mice[max].outcome=WIN;
		  		que[front]=0;//出队
				temp++;//出队1个 temp++  
			}
			else 
			{
				que[front]=0;//出队
				temp++;//出队1个 temp++  
			}
		  } 
		  
		  if(temp%ng==0||i==rear)//每轮的ng个数找出最大的存入队列中 
		  {
		  	que[++rear1]=max;
		  	mice[que[rear1]].outcome=WIN; 
		  	mice[que[rear1]].cycle=cycle;
		  	temp=0; 
		  } 
	   } 
	   
	   
	   //如果 front=rear && front1 == rear1-1  存在rear1的为最后一轮的王者
	   if(front==rear && rear1==0)//最后存入的只有一个数
	   {
	   	 mice[que[0]].cycle = cycle;//活到最后的王者
		 mice[que[0]].outcome = WIN; 
		 break;
	   } 
	   
	   //一轮过去
	   rear = rear1;
	   rear1 = -1;
	   front = front1;//固定为 -1 
	   cycle++; 
   } 
   
   
   //输出模块 
   //检查 老鼠在第几轮赢得胜利 
//   for(int i=0;i<np;i++)
//   {
//   	printf("%d in cycle %d ",mice[i].weight,mice[i].cycle);
//   	if(mice[i].outcome==WIN)printf("WIN\n");
//   	else printf("FAL\n");
//   }
//   
   int maxCycle = mice[que[0]].cycle;
//   printf("maxCycle:%d\n",maxCycle); 
   int number=1;
   mice[que[0]].rank=number;//第一名
   temp=1;//第一名有1个 
   while(maxCycle != 0)
   {
   	   maxCycle--;
   	   number=number+temp;
   	   temp =0;//每轮的赢家 并列名次的个数 
	   for(int i=0;i<np;i++)
	   {
	   	if(mice[i].cycle==maxCycle && mice[i].outcome==WIN)
	   	{
	   		mice[i].rank=number; 
	   		temp++;
		}

	   	if(mice[i].cycle==1 && mice[i].outcome==FAL)
	   	mice[i].rank=number;
	   }
   } 
   
   for(int i=0;i<np;i++)
   {
   	if(i==0)
   	printf("%d",mice[i].rank);
   	else printf(" %d",mice[i].rank);
   }

	
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值