PAT甲级1056 【Mice and Rice】 (25)

5 篇文章 0 订阅

补充: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;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值