牛客练习赛 11

A 假的线段树

链接:https://www.nowcoder.com/acm/contest/59/A
来源:牛客网
题目描述
给你一个长为n的序列a,有m次操作
1.把区间[l,r]内所有x变成y
2.查询区间[l,r]内第k小值
输入描述:
第一行两个数n,m,第二行n个数表示序列a,后面m行
1 l r x y :把区间[l,r]中所有x变成y
2 l r k :查询区间[l,r]中的第k小值
输出描述:
对于每个询问,输出一个数表示答案
示例1
输入
3 3
2 3 3
2 1 3 1
1 1 3 3 1
2 1 3 2
输出
2
1
备注:
对于100%的数据,1 <= n, m , ai <= 1000

分析:
数据范围不大暴力,按照题目模拟,查找第k大值时,sort和nth_element都能过;

#include 
#include 
#include 
using namespace std;
int a[2010], b[2010];

int main() {
    int n, m; 
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
    }
    while(m--) {
        int op, L, R, x, y;
        scanf("%d", &op);
        if(op == 1) {
            scanf("%d %d %d %d", &L, &R, &x, &y);
            for(int i = L; i <= R; i++) {
                if(a[i] == x) {
                    a[i] = y;
                }
            }
        }
        else {
            scanf("%d %d %d", &L, &R, &x);
            for(int i = L; i <= R; i++) {
                b[i - L + 1] = a[i];
            }
        //  sort(b + 1, b + R - L + 2);
            nth_element(b + 1, b + x, b + R - L + 2);
            printf("%d\n", b[x]);
        }
    }
    return 0;
}

D 求距离

链接:https://www.nowcoder.com/acm/contest/59/D
来源:牛客网
题目描述
给你一个1 -> n的排列,现在有一次机会可以交换两个数的位置,求交换后最小值和最大值之间的最大距离是多少?
输入描述:
第一行一个数n,之后一行n个数表示这个排列
输出描述:
输出一行一个数表示答案
示例1
输入
5
4 5 1 3 2
输出
3
说明
把1和2交换后
序列为4 5 2 3 1
最大值5在数组的2位置,最小值1在数组的5位置距离为3
备注:
对于100%的数据,1 <= n <= 100

分析:
把最大值最小值的位置保存下来,固定一个,另一个放置左端或右端,枚举四个答案;

#include 
#include 
#include 
using namespace std;

int main() {
    int n, maxn, minn, k;
    int maxn_id = 1, minn_id = 1;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &k);
        if(i == 1) {
            maxn = k;
            minn = k;
        }
        if(maxn < k) {
            maxn = k;
            maxn_id = i;
        }
        if(minn > k) {
            minn = k;
            minn_id = i;
        }
    }
    int ans1 = minn_id - 1;
    int ans2 = max(ans1, maxn_id - 1);
    int ans3 = max(ans2, n - minn_id);
    int ans4 = max(ans3, n - maxn_id);
    printf("%d\n", ans4);
    return 0;
}

E 求最值

链接:https://www.nowcoder.com/acm/contest/59/E
来源:牛客网
题目描述
给你一个长为n的序列a,定义 f(i,j)=(ij)2+g(i,j)2 f ( i , j ) = ( i − j ) 2 + g ( i , j ) 2
g是这样的一个函数:

求最小的 f(i,j) f ( i , j ) 的值, i!=j i ! = j
输入描述:
第一行一个数n,之后一行n个数表示序列a
输出描述:
输出一行一个数表示答案
示例输入
4
1 0 0 -1
输出
1
备注:
对于100%的数据,2 <= n <= 100000 , |ai| <= 10000

分析:
我选择暴力1000项,数据水给过了。。。
题解是转化成平面最近点对,O(nlogn);

#include 
#include 
#include 
using namespace std;
typedef long long LL;

const int MAXN = 1e5 + 10;
LL a[MAXN], sum[MAXN];

int main() {
    int n; 
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%lld", &a[i]);
        sum[i] += sum[i - 1] + a[i];
    }
    LL cnt, ans = a[1] * a[1] + 1;
    for(int i = 1; i <= n; i++) {
        for(int j = max(i - 1000, 0); j < i; j++) {
            if(abs(sum[i] - sum[j]) > 1e4) continue;
            cnt = (i - j) * (i - j) + (sum[i] - sum[j]) * (sum[i] - sum[j]);
            ans = min(ans, cnt);
        }
    }
    printf("%lld\n", ans);
    return 0;
}

你可能感兴趣的:(比赛,STL)