题目链接:点击打开链接
题目大意:
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; }