1. 程式人生 > >ZOJ - 3981 - Balloon Robot (思維)

ZOJ - 3981 - Balloon Robot (思維)

iostream 求一個 給他 lld min .net uri class 計算

參考自:https://blog.csdn.net/qq_36553623/article/details/78445558

題意:

第一行三個數字n, m, q表示有m個座位圍成一個環,n個隊伍,q次A題

接下來n個數表示n個隊伍所在位置(1<=ai<=m)

再接下來q行,每行a, b表示第a個隊伍在第b秒A了一道題

有一個只會每一秒順時針移動一個位置的發氣球機器人

只要當前隊伍有題目已經A了就會給他對應數量的氣球(當然每道題最多1個氣球)

如果a隊伍在b時刻A了一道題,並在c時刻才拿到氣球,那麽這個隊伍就會積累c-b點不開心值

求一個機器人起始位置(一開始是第0秒)使得所有隊伍最終不開心值之和最小

思路:

對於一次ac,不開心值 = 當前位置 - 初始位置 - ac時間 也就是 不開心值 = a[i] - 1 - time

假設機器人現在是在1位置,計算出了所有交題的不開心值的和sum,現在改變初始位置1,變為x

現在的不開心值 = sum - 改變位置後減少的時間 + 改變位置後增加的時間

改變位置後減少的時間 = (p - x) * dis[x]

改變位置後增加的時間 = (m - dis[x]) * x

sum - (p - x) * dis[x] + x * (m - dis[x]) = sum + m * x - dis[x] * p

代碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e6+10;
ll dis[maxn], a[maxn];
int main() {
    ll t, n, m, p;
    scanf("%d", &t);
    while(t--) {
        ll x, time, sum = 0;
        scanf("%lld %lld %lld", &n, &m, &p);
        for(int i = 1; i <= n; i++) {
            scanf("%lld", &a[i]);
        } 
        for(int i = 0; i < p; i++) {
            scanf("%lld %lld", &x, &time);
            dis[i] = (a[x]-1-time+m) % m;
            sum += dis[i];
        }
        ll ans = 0x3f3f3f3f3f3f3f3fLL; 
        sort(dis,dis+p);
        for(int i = 0; i < p; i++) {
            ans = min(ans, sum+m*i-dis[i]*p);
        }
        printf("%lld\n", ans);
    }
    return 0;
} 

ZOJ - 3981 - Balloon Robot (思維)