P1583 魔法照片

文章介绍了一种算法,通过优先级排序和类别调整权值,找出在给定条件下,权值最高的前k个人的编号。
摘要由CSDN通过智能技术生成

# 魔法照片

## 题目描述

一共有 $n$ 个人(以 $1\sim n$ 编号)向佳佳要照片,而佳佳只能把照片给其中的 $k$ 个人。佳佳按照与他们的关系好坏的程度给每个人赋予了一个初始权值 $W_i$。然后将初始权值从大到小进行排序,每人就有了一个序号 $D_i$(取值同样是 $1\sim n$)。按照这个序号对 $10$ 取模的值将这些人分为 $10$ 类。也就是说定义每个人的类别序号 $C_i$ 的值为 $(D_i-1)\bmod 10 +1$,显然类别序号的取值为 $1 \sim 10$。第 $i$ 类的人将会额外得到 $E_i$ 的权值。你需要做的就是求出加上额外权值以后,最终的权值最大的 $k$ 个人,并输出他们的编号。**在排序中,如果两人的 $E_i$ 相同,编号小的优先。**

## 输入格式

第一行输入用空格隔开的两个整数,分别是 $n$ 和 $k$。

第二行给出了 $10$ 个正整数,分别是 $E_1\sim E_{10}$。

第三行给出了 $n$ 个正整数,第 $i$ 个数表示编号为  $i$ 的人的权值 $W_i$。

## 输出格式

只需输出一行用空格隔开的 $k$ 个整数,分别表示最终的 $W_i$ 从高到低的人的编号。

## 样例 #1

### 样例输入 #1

```
10 10
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
```

### 样例输出 #1

```
10 9 8 7 6 5 4 3 2 1
```

## 提示

对于 $100\%$ 的数据,$1\leq n\leq 20000$,$1\leq k\leq n$,保证所有数据均在 `int` 范围之内。

一道比较简单的模拟题,就是题目读的有点迷,大致意思就是给我们两个数组,第一个数组是一个只有10个元素的数组,e[i]表示当这个人的类别是i时,其对应的权值要加上对应的值,第二个数组是初始全权值数组,w[i]表示佳佳对这个人的好坏程度,题目要求我们要求出加上对应值后权值最大的前k个人的编号,注意!!!,这里是编号!!,根据题意模拟整个过程即可,首先我们要对w数组进行排序(降序),注意我们要保存编号,方便后面输出答案,然后根据降序是w数组加上对应类别的e[i],然后再对w数组排序(降序),输出前k个人的编号即可

注意在排序的时候要将其编号一起变动

附上代码

#include<stdio.h>
#define N  20010
int w[N],b[N],e[10];
int main()
{
    int n,k;
    scanf("%d %d",&n,&k);
    for(int i=0;i<10;i++)
        scanf("%d",&e[i]);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&w[i]);
        b[i]=i+1;
    }
    for(int i=0;i<n-1;i++)
        for(int j=i+1;j<n;j++)
        {
            if(w[i]<w[j])
            {
                int temp=w[i];
                w[i]=w[j];
                w[j]=temp;
                int temp1=b[i];
                b[i]=b[j];
                b[j]=temp1;
            }
            if(w[i]==w[j]&&b[i]>b[j])
            {
                int temp=b[i];
                b[i]=b[j];
                b[j]=temp;
            }
        }
    for(int i=0;i<n;i++)
        w[i]+=e[i%10];
    for(int i=0;i<n-1;i++)
        for(int j=i+1;j<n;j++)
        {
            if(w[i]<w[j])
            {
                int temp=w[i];
                w[i]=w[j];
                w[j]=temp;
                int temp1=b[i];
                b[i]=b[j];
                b[j]=temp1;
            }
            if(w[i]==w[j]&&b[i]>b[j])
            {
                int temp=b[i];
                b[i]=b[j];
                b[j]=temp;
            }
        }
    for(int i=0;i<k;i++)
        printf("%d ",b[i]);
    return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值