Visiting Peking University 2017ACM-ICPC亚洲区(北京赛区)网络赛题目1

**题意:**Ming 打算旅游 n 天,其中 m 天在北京玩。他打算抽这 m 天中的第一天和另外一天去北大看看。为此他获得了这 n 天的北大的参观人数,他想选择人数相加和最少的两天去。又由于北京有交通管制,交通管制的当天哪也不能去,所以当 m 天中有几天交通管制,那么 Ming 就在北京多待几天。

思路:理清题意后这题并不难,不过刚开始实现的时候有点绕。告诉我们哪几天是交通管制,然后那几天就不能算在 m 天之内。我们事先将交通管制的那几天从 n 天里删去,提前利用另外的数组记录哪一个人数对应的是哪一天。这样处理后我们就只需要对这些剩下的人数从前往后扫一遍,找到对应的 m 天里的最少人数的两天即可。

拿题目中的第一个样例举个例子:
输入为:
7 3
6 9 10 1 0 8 35
3 5 6 2
读取操作后:
p数组:6,9,10,1,0,8,35
id数组:0,1,2,3,4,5,6
用bool数组记录哪天是交通管制,可见第 5、6、2 天交通管制。将这几天从 p 数组和 id 数组中删掉:
p 数组:6,9,1,0
id 数组:0,1,3,4

接下来从前往后遍历,当 m 天的第一天是第 0 天时,,,当 m 天的第一天是第 1 天时,,,

代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<utility>
#include<vector>
#include<cmath>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;

const int INF = 0x3f3f3f3f;

int N,M;
int p[210];
int id[210];
bool flag[210];

int main()
{
    //freopen("in.txt", "r", stdin);

    while(scanf("%d%d", &N, &M) == 2){
        memset(flag, false, sizeof(flag));

        for(int i=0; i<N; i++){
            scanf("%d", &p[i]);
            id[i] = i;
        }
        int q;
        scanf("%d", &q);
        for(int i=0; i<q; i++){
            int tmp;
            scanf("%d", &tmp);
            flag[tmp] = true;
        }

        //下面这段就是把交通管制日从 p 数组和 id 数组中删掉
        N -= q;
        int pos = 0;
        for(int i=0; i<N; i++,pos++){
            if(!flag[pos]){
                p[i] = p[pos];
                id[i] = id[pos];
            }
            else{
                i--;
            }
        }

        int beg = 0;
        int a, b;
        int minn = INF;
        while(beg+M-1 < N){
            //printf("beg = %d\n", beg);
            int pos;
            for(int i=1; i<M; i++){
                if(minn > p[beg+i]+p[beg]){
                    minn = p[beg+i]+p[beg];
                    a = beg;
                    b = beg+i;
                }
            }

            beg++;
        }
        printf("%d %d\n", id[a], id[b]);
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值