衡八联考一
本来会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