UVA 11898 - Killer Problem(鸽笼原理+计数排序+大力出奇迹)

来源:互联网 发布:淘宝的旗舰店靠谱吗 编辑:程序博客网 时间:2024/04/27 20:07

UVA 11898 - Killer Problem

题目链接

题意:给定一个序列,每次询问一个[l,r],求出这个区间中选取两个不同位置的数字,他们的绝对值最小

思路:想线段数,树状数组,RMQ之类搞,根本想不通怎么搞,于是看了下别人的讨论,发现居然是大力出奇迹,不过还是有用到点原理,就是由于数字最多1W,如果询问区间超过1W的话,必然会有两个一样的数字,绝对值就是0了,这样一剪,再利用计数排序去找靠近的两两个数字,就能过了,复杂度为O(10^8)

代码:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 200005;const int M = 10005;int t, n, num[N], cnt[M];int main() {    scanf("%d", &t);    while (t--) {scanf("%d", &n);for (int i = 1; i <= n; i++)    scanf("%d", &num[i]);int q, l, r;scanf("%d", &q);while (q--) {    scanf("%d%d", &l, &r);    if (r - l + 1 >= 10000) {printf("0\n");continue;    }    memset(cnt, 0, sizeof(cnt));    int flag = 1, Max = 0;    for (int i = l; i <= r; i++) {cnt[num[i]]++;Max = max(Max, num[i]);if (cnt[num[i]] == 2) {    printf("0\n");    flag = 0;    break;}    }    if (flag) {int pre = -1;int ans = 10000;for (int i = 1; i <= Max; i++) {    if (cnt[i]) {if (pre != -1)    ans = min(ans, i - pre);pre = i;    }}printf("%d\n", ans);    }}    }    return 0;}


0 0
原创粉丝点击