[SMOJ1043]选凳子 ( 2016 创新班 )

来源:互联网 发布:怎样注销淘宝店铺 编辑:程序博客网 时间:2024/04/28 13:12

题目描述

从左往右有无限多张凳子,凳子的编号从左往右依次是:1,2,3,4,5,6……。有 N 只奶牛排着队正走过来,N 只奶牛的编号分别用1,2,3,4,… N 来表示。它们要找合适的凳子坐。每只奶牛选择凳子的规则都是:

  1. 奶牛都不喜欢太拥挤,于是奶牛选择的凳子左边 D 距离内不能有其它奶牛坐,右边 D 距离内也不能有奶牛坐。比如:两头奶牛,当 D =10时,一只奶牛选择编号是47的凳子,另一只选择编号是57的凳子,这是合法的。当 D =10时,一只奶牛选择编号是47的凳子,另一只选择编号是56的凳子,这是不合法的,因为他们之间的距离小于10。
  2. 对于第 i 只奶牛来说,它选择的凳子的编号必须大于或等于 Ai
  3. 在满足第(1)、第(2)点的前提下,奶牛会尽量选择编号小的凳子坐下来。

现在这 N 只奶牛按照编号从小到大的顺序排好了队,编号是1的奶牛排在最前面,它首先按照如上的规则选好凳子后就坐下来,接着是编号是2的奶牛选择凳子后坐下来,接着是编号是3的奶牛选择凳子后坐下来 ,……最后选择凳子的奶牛是第 N 只奶牛。
你的任务是:输出编号是1至 N 的奶牛,它们各自选择的凳子的编号。

输入格式 1043.in

多组测试数据。
第一行,一个整数 R,表示有 R 组测试数据。1R6
每组测试数据格式如下:
第一行,两个正整数,ND1N10001D106
第二行,N 个整数,第 i 个整数表示 Ai1Ai106

输出格式 1043.out

R 行,每行对应一组测试数据。
每组测试数据的输出都是一行,该行包含 N 个整数,空格分开,第 i 个整数表示第 i 只奶牛选择的凳子的编号。

输入样例 1043.in

5
4 10
1 21 11 7
4 11
1 21 11 7
4 1000000
1000000 1000000 1000000 1
4 999999
1000000 1000000 1000000 1
4 1
8 7 5 1

输出样例 1043.out

1 21 11 31
1 21 32 43
1000000 2000000 3000000 4000000
1000000 1999999 2999998 1
8 7 5 1


最近做多了线段树的题,第一反应就是写个线段树维护一下凳子被占用的情况,似乎是可行的,只是没有注意到数据范围。而且有无限多张椅子,理论上是不可能在真正意义上实现的。样例在本地过了,一提交却 MLE 。

于是又想起 lws 的最高指示:“数据量决定算法。”发现牛的数量其实是很少的,可以从这一点入手。

也就是说,对于每一头牛,都可以将其与之前已经安排好位置的牛进行对比,从而选出合适的位置。但在对比时要注意,之前的奶牛要按顺序排好,否则可能会出现为了满足后面的奶牛但却与前面的奶牛冲突的情况。因此每确定一头奶牛的位置都重新排一次序,总的时间复杂度为 O(n2log2n)

参考代码:

#include <algorithm>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>using namespace std;const int maxn = 1e6 + 10;int a[maxn], b[maxn];int main(void) {    freopen("1043.in", "r", stdin);    freopen("1043.out", "w", stdout);    int r;    scanf("%d", &r);    while (r--) {        int n, d;        scanf("%d%d", &n, &d);        for (int i = 0; i < n; i++) scanf("%d", &a[i]);        for (int i = 0; i < n; i++) {            b[i] = a[i];            for (int j = 0; j < i; j++)                if (abs(b[i] - b[j]) < d) b[i] = b[j] + d;            printf("%d ", b[i]);            sort(b, b + i + 1);        }        putchar('\n');    }    return 0;}
0 0
原创粉丝点击