题目链接:点击打开链接
题目大意:
1、赶脚这道题目读懂题目比写出代码要难多了……
2、把题目中的例子分析一遍你就懂了:
1)input中的第三行是索引,表示的是以第三行索引的顺序进行比较,也就是说第6、0、8个mice先组成一组进行比较,而这3个mice吃到的rice就是第二行中对应的值19、25、57,因此第8个mice吃到的是57数量最多晋级,同理第7、10、5个mice吃到的rice是22、10、3,第7个晋级,第9、1、4个mice吃到的rice是56、18、37,第9个晋级,剩下的只有第2、3个mice,分别吃到的rice是0、46,第3个晋级,于是第8、7、9、3一共4个mice晋级到下一轮,并继续按照这个顺序比较,那么其他没有晋级的mice的排名都是第5名。
2)第8、7、9、3个mice吃到的rice分别是57、22、56、46,前三个中第8个晋级,剩下的第3个也晋级,所以未晋级的7、9的排名都是第3。
3)第8、3个mice的排名分别是第1和第2了。
3、这里有一点比较关键的就是未晋级的mice的排名名次的计算,知道了当前要比赛的mice的数量之后就可以计算出一共会有多少晋级,那么未晋级的mice的名次就都是本轮晋级数目+1了。
解题思路:略。
AC 代码
#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f
#define MOD 1000000007
using namespace std;
typedef long long ll;
int rks[1100], wrr[1100], irr[1100];
struct node
{
int id,val;
}nds[1100];
vector<node> v;
int cmp(node n1, node n2)
{
return n1.val>n2.val;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<n;i++) scanf("%d",&wrr[i]);
for(int i=0;i<n;i++) scanf("%d",&irr[i]);
for(int i=0;i<n;i++)
{
nds[i].id=irr[i];
nds[i].val=wrr[irr[i]];
}
/*
0 3
3 6
6 9
9
*/
queue<node> q;
for(int i=0;i<n;i++) q.push(nds[i]);
while(1)
{
v.clear();
while(!q.empty()) // 筛选好下一次的比较node
{
v.push_back(q.front());
q.pop();
}
if(v.size()==1) break; // 注意是1 不是0
int len=v.size(), rk=len%m==0?len/m+1:len/m+2, i;
for(i=0;i+m<=len;i+=m) // 过程筛选
{
sort(v.begin()+i,v.begin()+i+m,cmp);
q.push(v[i]);
for(int j=i+1;j<i+m;j++) rks[v[j].id]=rk;
}
if(len%m!=0) // 防止最后一次有余处理
{
sort(v.begin()+i,v.end(),cmp);
q.push(v[i]);
for(int j=i+1;j<len;j++) rks[v[j].id]=rk;
}
// for(int i=0;i<n;i++)
// printf("%d%c",rks[i],i==n-1?'\n':' ');
}
rks[v[0].id]=1;
for(int i=0;i<n;i++)
printf("%d%c",rks[i],i==n-1?'\n':' ');
}
return 0;
}
转载:https://blog.csdn.net/yangsongtao1991/article/details/43417363