PAT甲级1056 Mice and Rice

题解

题目要表达的意思特别绕,没看翻译之前,一度怀疑自己的水平?首先给你一个随机比赛序列。然后每NG个数的人在一个小组比赛。这个小组最肥的老鼠参加下一场比赛,在这一轮(所有的小组赛比完)淘汰的赋予排名,胜利的进入下一场比赛,重复上面的操作,一直找出冠军。
注意:到最后不足NG人也被视为一组

就拿题目中的数据来说:
6 0 8 一组 7 10 5 一组 9 1 4 一组 2 3 一组
4组最多诞生4个强人。所以所有淘汰的人排名是 5;
然后
8 7 9 3 作为优胜者参加下一场比赛
8 7 9 一组 3 一组
诞生2个强人。所有淘汰的人排名是 3;
8 3 一组
诞生1个强人(就是冠军)。所有淘汰的人排名是 1;
8

思路

1.向量数组weight,order,rank分别存老鼠重量、比赛顺序和排名,其中order数组动态存储当前比赛的人,即每次小组赛后删除败者
2.分组找出小组冠军,其他败者重量标记为-1,并赋值对应id的排名
3.赛后删除重量标记为-1的id
4.剩下的就是一些细节了,写的时候经常运行debug一下,不然整个程序写好后找bug真的很累

#include
#include
using namespace std;
int main()
{
    int np,ng;
    cin>>np>>ng;
    vector<int> weight(1005),rank(1005,-1);
    vector<int> order(np);
    for(int i=0;i<np;i++)
    {
        cin>>weight[i];//第i只老鼠的重量
    }
    for(int i=0;i<np;i++)
    {
        cin>>order[i];//比较顺序
    }
    int cur=np,currank;//cur当前人数,currank当前排名
    while(cur>1)//下一场比赛的人数
    {
        currank=cur/ng+1;//当前败者排名
        if(cur%ng)currank++;//最后一组虽然人数不足,
		//但是还存在 
        for(int i=0;i<order.size();i+=ng)//一场比赛中组数 
        {
       	  	int maxwe=-1;
        	int pre=-1;//标记上一个最大值 
			for(int j=i;j<order.size()&&j<i+ng;j++)
        	{
        		if(weight[order[j]]>maxwe)//更新最大值 
        		{
		        	 if(pre!=-1)//上一个最大值删除
		        	 {
 	        			weight[order[pre]]=-1;
 	        			rank[order[pre]]=currank;
 	        		 }
					 maxwe=weight[order[j]];
					 pre=j;
		        }
		        else 
		        {
        			weight[order[j]]=-1;
        			rank[order[j]]=currank;
        		}
	        }
        }
        for(int j=0;j<order.size();)
       	{
       		if(weight[order[j]]==-1)
       		{
				order.erase(order.begin()+j);
    		}
    		else j++;
     	}
		if(cur%ng) cur=cur/ng+1;
		else cur=cur/ng;
    }
    for(int i=0;i<np;i++)
    {
		if(i!=0)
		{
			cout<<" ";
			cout<<(rank[i]==-1?1:rank[i]);
		}
		else cout<<(rank[i]==-1?1:rank[i]); 
    }
    return 0;
}

你可能感兴趣的:(PAT甲级)