【PAT A1056】Mice and Rice


Ideas
simulation game that should not be difficult, the book which is a queue, the process is not difficult to find traverse the level of the game is somewhat similar to the tree, but it is traversed from the bottom up; I was with the whole priority queue, after all, he has only concern priority features the highest level, it is still on. I was a little bit of a headache is ranking the beginning I was first of all nouns are set to 1, and then save the loser with a vector, this vector right after each round of people's ranking will increase by one, which obviously does not match the meaning of the questions, even if said in comments like three people tied for first, fourth and fourth person is not the second, then the next question is similar to the ranking, and I get the ranking in advance like a fraction , the same score means that the same ranking, according to these scores was re-arranged for the name, like a long time thought a good way, if you have friends there is a good way I hope to dance, grateful. But the book is very smart, the number who qualify for the round plus it is just a round loser ranking, powerful ah!

#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

struct programmer
{
	int rank;
	int weight;
}programmers[1010];

struct cmp {
	bool operator () (int A, int B){
		return programmers[A].weight < programmers[B].weight;
	}
};

int main(){
	//total num of programmers, num of programmers in one group
	int NP, NG;
	scanf("%d%d", &NP, &NG);
	for(int i = 0; i < NP; i++){
		scanf("%d", &programmers[i].weight);
		programmers[i].rank = 1;
	}
	//loser用来存储失败者的序号,winner用来存每轮的参赛者的序号
	vector<int> loser;
	queue<int> winner;
	for(int i = 0; i < NP; i++){
		int order;
		scanf("%d", &order);
		winner.push(order);
	}


	//如果参赛者大于1说明还有比赛,则继续循环,每一次循环是一轮比赛
	while(winner.size() > 1){
		int cnt = winner.size();
		//用优先队列来组织每一组比赛
		priority_queue<int, vector<int>, cmp> q;
		for(int i = 0; i < cnt; i++){
			q.push(winner.front());
			winner.pop();//参加了比赛就把他从参赛者中删除
			//组满了或者最后一组人数不够
			if(q.size() == NG || (q.size() > 0 && i == cnt - 1)){
				//每一组最大者进入下一轮
				winner.push(q.top());
				q.pop();
				//每一组的败者全部到loser里面去
				while(!q.empty()){
					loser.push_back(q.top());
					q.pop();
				}
			}
		}
		//没过完一轮,把败者的名词加1,注意这里假如3人并列第一,第四个人不是第四名
		//而是3人并列第一,第四人是第二名
		for(int i = 0; i < loser.size(); i++)
			programmers[loser[i]].rank++;
	}


	//重新修改名词,此时3人并列第一,第四人是第4名
	loser.push_back(winner.front());//把第一名也放进来,方便统一修改
	int max = programmers[loser[0]].rank;//表示要修改几轮
	int cnt = 0, before = 0;//cnt记录已经修改了多少人的名次,before是前面这些人是第几名
	//每次修改原名词为i的programmer
	for(int i = 1; i <= max; i++){
		while(cnt < loser.size() && programmers[loser[loser.size() - 1 - cnt]].rank == i){
			programmers[loser[loser.size() - 1 - cnt]].rank = before + 1;
			cnt++;
		}
		before = cnt;
	}

	//标准输出
	for(int i = 0; i < NP; i++){
		if(i == 0)
			printf("%d", programmers[i].rank);
		else
			printf(" %d", programmers[i].rank);
	}
	printf("\n");

	return 0;
}
Published 30 original articles · won praise 1 · views 10000 +

Guess you like

Origin blog.csdn.net/lvmy3/article/details/104174812