题意:现在有n只队伍分布在m张桌子上(每个队伍在一张桌子上),现在有一个送气球的机器人,初始位置可以是这m个桌子的任意一个,机器人沿着顺时针方向沿着桌子走,如果机器人所在位置有队伍A了题目,机器人就会送上气球。现在如果某个队伍在Ta时刻A了题目,然后气球在Tb时刻被送到,那么此时的不开心值就有Tb-Ta。现在要使所有队伍的不开心值总和最小,问机器人一开始应该位于哪里。
题解:我们假设开始的时候机器人在1号位置, 那么可以得到一个怒气值,如果机器人往后移动一个是不是所有的怒气值都要-1,如果机器人走过一个人,那么怒气值就要+m应该需要下一圈才能再回到刚才走过的那个人,明白了这个我们就可以跑那些事件即可。
a c c o d e : ac\ code: ac code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define g getchar()
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define per(i, a, b) for(int i = a; i >= b; i--)
#define met(a, b) memset(a, b, sizeof(a))
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
inline int read() {
int x = 0, f = 1;
char ch = g;
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = g;}
while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = g;}
return f * x;
}
int T, n, m, p, s[maxn], unh[maxn];
pair<int, int> pro;
int main() {
T = read();
while(T--) {
n = read();
m = read();
p = read();
rep(i, 1, n) s[i] = read();
rep(i, 1, p) {
pro.first = read(), pro.second = read();
if(pro.second % m <= s[pro.first] - 1) unh[i] = s[pro.first] - 1 - pro.second % m;
else unh[i] = m - (pro.second % m - s[pro.first] + 1);
}
sort(unh + 1, unh + 1 + p);
ll ans = LONG_MAX, ti = 0, now = 0;
rep(i, 1, p) now += unh[i];
rep(i, 1, p) {
ans = min(ans, now - (ll)(unh[i] - ti) * p);
if(i <= p - 1) {
now = now - (ll)(unh[i] - ti + 1) * p + m;
ti = unh[i] + 1;
}
}
printf("%lld\n", ans);
}
return 0;
}