衡八联考一


本来会T1,结果文件写错了,爆0了

A 饼干

题目大意 : n个饼干,每个有个值,水也有个值,最开始先喝口水,然后吃每个饼干的时候都会获得abs(a[i]-lt)的收益,lt是上一次吃的饼干或喝水的价值,问安排吃饼干喝水的顺序收益最小最大是多少

  • 最小值好求,就是先喝水,然后吃第一个比水大的饼干,然后一直吃比上一个大的,吃完最大的,然后再喝水,然后吃第一个比水小的,然后一直吃小的,所以答案是最大值减最小值

  • 最大值肯定就是先吃最大,再吃最小,然后吃次大,再吃次小。或者先吃最小,所以就两个都跑一遍

  • 然后考虑喝水的问题,发现喝水只会对当前这个饼干产生影响,所以如果喝水优就喝水就行

Code

Show Code
#include <cstdio>
#include <algorithm>
#define abs(x) (x < 0 ? -(x) : x)

using namespace std;
const int N = 1e5 + 5;

int read(int x = 0, int f = 1, char c = getchar()) {
    for (; (c < '0' || c > '9'); c = getchar()) if (c == '-') f = -1;
    for (;!(c < '0' || c > '9'); c = getchar()) x = x * 10 + c - '0';
    return x * f;
}

int n, m, a[N], mx, mi;
long long ans1, ans2;

int main() {
    freopen("biscuits.in", "r", stdin);
    freopen("biscuits.out", "w", stdout);
    n = read(); mx = mi = m = read();
    for (int i = 1; i <= n; ++i) {
        a[i] = read();
        mx = max(mx, a[i]);
        mi = min(mi, a[i]);
    }
    sort(a + 1, a + n + 1);
    int lt = m;
    for (int l = 1, r = n; l <= r; ++l, --r) {
        ans1 += max(abs(a[l] - lt), abs(a[l] - m)), lt = a[l];
        if (l != r) ans1 += max(abs(a[r] - lt), abs(a[r] - m)), lt = a[r];
    }
    lt = m;
    for (int l = 1, r = n; l <= r; ++l, --r) {
        ans2 += max(abs(a[r] - lt), abs(a[r] - m)), lt = a[r];
        if (l != r) ans2 += max(abs(a[l] - lt), abs(a[l] - m)), lt = a[l];
    }
    printf("%d %lld\n", mx - mi, max(ans1, ans2));
    return 0;
}

B 死线

题目大意 : 第i个任务需要在a[i]天前完成,每次操作只能交换相邻的任务,问最少操作多少次能完成所有任务

  • 从最后一天开始考虑,第i天完成的任务一定得是a值大于等于i的

  • 如果确定了哪天完成那个任务,其实操作次数就是逆序对数,这个应该除了我都会

  • 于是就是然逆序对数最少,然后第i天调的任务一定是最靠后的那个,所以优先队列维护就好了

Code

Show Code
#include <queue>
#include <cstdio>
#include <vector>

using namespace std;
const int N = 2e5 + 5;

int read(int x = 0, int f = 1, char c = getchar()) {
    for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = -1;
    for (; c >='0' && c <='9'; c = getchar()) x = x * 10 + c - '0';
    return x * f;
}

priority_queue<int> q;
vector<int> a[N];
int n, t[N], p[N];
long long ans;

void Add(int x) {
    for (; x <= n; x += x & -x) t[x]++;
}

int Ask(int x, int ans = 0) {
    for (; x; x -= x & -x) ans += t[x];
    return ans;
}

int main() {
    freopen("deadline.in", "r", stdin);
    freopen("deadline.out", "w", stdout);
    n = read();
    for (int i = 1; i <= n; ++i)
        a[read()].push_back(i);
    for (int i = n; i >= 1; --i) {
        for (int j = 0; j < a[i].size(); ++j)
            q.push(a[i][j]);
        if (q.empty()) return puts("-1"), 0;
        p[i] = q.top(); q.pop();
    }
    for (int i = n; i >= 1; --i) 
        ans += Ask(p[i]), Add(p[i]);
    printf("%lld\n", ans);
    return 0;
}

C 迷宫 (Unaccepted)

题目大意 :

Code

Show Code
posted @ 2021-03-25 14:10  Shawk  阅读(45)  评论(0编辑  收藏  举报