补充:2018.8.19更新,哦凑再写一遍果然思路清晰了很多,代码也缩减到了47行。用一个vector数组group记录当前所有的比赛顺序,再按每ng个进行从前往后分组,将每个小组第一push到vector数组tem中,其余不是小组第一的排名就是当前tem数组的大小加1(因为有了前tem名),然后令group等于tem,继续循环,最后将仅存的一个人排名设为第一。以及ng的范围是小于1e3,np的范围大的多,数组开到1e6防止越界。
C++
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int maxn = 1e6+10;
vector<int> tem, group;
int w[maxn], rnk[maxn], out[maxn];
int main(){
//freopen("aa.txt", "r", stdin);
int np, ng, num;
cin >> np >> ng;
for(int i = 0; i<np; i++){
cin >> w[i];
}
for(int i = 0; i<np; i++){
cin >> num;
group.push_back(num);
}
int maxx, idx = 0;
while(group.size() != 1){
tem.clear();
for(int i = 0; i<group.size(); i+=ng){
maxx = w[group[i]], idx = group[i];
for(int j = i; j<i+ng; j++){
if(w[group[j]] > maxx){
maxx = w[group[j]];
idx = group[j];
}
out[group[j]] = 1;
}
tem.push_back(idx);
out[idx] = 0;
}
for(int i = 0; i<group.size(); i++){
if(out[group[i]]){
rnk[group[i]] = tem.size()+1;
}
}
group = tem;
}
rnk[idx] = 1;
for(int i = 0; i<np; i++){
cout << rnk[i];
i != np-1 ? cout << " " : cout << "\n";
}
return 0;
}
模拟题,注意最后一组如果不满足比赛人数也要进行比赛,角逐出小组第一。另外比较头疼的是最后的排名。。我用了比较笨的方法。。。
Object C
#include<stdio.h>
typedef struct Node{
int w;
int idx;
int rank;
}Node;
Node node[1010];
int cmp(const void *a, const void *b){
Node *n1 = (Node *)a, *n2 = (Node *)b;
if(n1->w != n2->w) return n2->w-n1->w;
return n1->idx-n2->idx;
}
int cmp2(const void *a, const void *b){
Node *n1 = (Node *)a, *n2 = (Node *)b;
return n1->idx-n2->idx;
}
int arr[1010], rank[1010], st[1010], tem[1010];
int main(){
//freopen("in.txt", "r", stdin);
int m, k, i, j, cnt = 0, len = 0;
scanf("%d %d", &m, &k);
for(i = 0; i<m; i++)
scanf("%d", &arr[i]);
for(i = 0; i<m; i++)
scanf("%d", &st[i]);
for(i = 0; i<m; i+=k){
int max = arr[st[i]], maxidx = st[i];
for(j = i; j<i+k&&j<m; j++){
if(max < arr[st[j]]){
max = arr[st[j]];
maxidx = st[j];
}
rank[st[j]] = cnt;
}
rank[maxidx]++;
tem[len++] = maxidx;
}
cnt++;
while(len > 1){
int temlen = 0;
for(i = 0; i<len; i+=k){ //代码重用千万要注意一些边界条件的变化,尽可能不要完全复制!!
int max = arr[tem[i]], maxidx = tem[i];
for(j = i; j<i+k&&j<len; j++){
if(max < arr[tem[j]]){
max = arr[tem[j]];
maxidx = tem[j];
}
rank[tem[j]] = cnt;
}
rank[maxidx]++;
tem[temlen++] = maxidx;
}
cnt++;
len = temlen;
}
for(i = 0; i<m; i++){
node[i].idx = i;
node[i].w = rank[i];
}
qsort(node, m, sizeof(node[0]), cmp); //第一趟排序获取权重排行
node[0].rank = 1;
for(i = 1; i<m; i++){
if(node[i].w == node[i-1].w) node[i].rank = node[i-1].rank;
else node[i].rank = i+1;
}
qsort(node, m, sizeof(Node), cmp2); //第二趟排序获取序号排行
for(i = 0; i<m; i++){
printf("%d", node[i].rank);
printf(i != m-1?" ":"\n");
}
return 0;
}