E. Air Conditioners

题目链接:https://codeforces.com/contest/1547/problem/E

题意:

给定长度为 n 的区间,这个区间内有 k 台空调,每台空调有其对应的温度,第 i 台空调的放置位置为 \(a_i\),温度设定为 \(t_i\),对于每个位置 \(i({1}\le{i}\le{n})\),其温度为 \(\underset{{1}\le{j}\le{k}}{min}(t_j+\vert{a_j-i}\vert)\),问 1~n 每个位置的温度为多少。
有 q 次询问,每次给定 n 和 k 以及每台空调的位置和温度,输出每个位置的温度。

思路:

用结构体表示空调,属性包括位置和设定温度,将空调按位置的前后顺序排序,再分别计算每个空调只影响其左边的位置的温度时每个位置的温度情况以及每个空调只影响其右边的位置的温度时每个位置的温度情况一个位置的温度即为这两种情况下该位置温度的较小值
从前往后按位置顺序从第一个空调的位置遍历到最后一个位置,将第一种情况每个位置的温度存入 pre 数组,再从后往前按位置倒序从倒数第一个空调的位置遍历到第一个位置,将第二种情况每个位置的温度存入 suf 数组,对于每个位置 \(i\) 的温度,输出 \(pre[i]\)\(suf[i]\) 中的较小者即可。(对于每组数据,每次要将 pre 数组和 suf 数组中的元素全部置为一个无穷大值)

代码:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 3e5 + 5;
typedef long long ll;
struct conditioner
{
    ll p, tem;
} c[maxn];
ll pre[maxn], suf[maxn], ans[maxn];
bool cmp(conditioner a, conditioner b)
{
    return a.p < b.p;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t;
    cin >> t;
    ll n, k;
    while (t--)
    {
        memset(pre, 0x3f, sizeof(pre));
        memset(suf, 0x3f, sizeof(suf)); //记得每次要将pre和suf数组置为无穷大值
        cin >> n >> k;
        for (int i = 0; i < k; i++)
            cin >> c[i].p;
        for (int i = 0; i < k; i++)
            cin >> c[i].tem;
        sort(c, c + k, cmp); //将空调按位置前后顺序排序
        ll kk = 0, pos = c[0].p, now = c[0].tem;
        while (pos <= n) //从第一个空调的位置遍历到最后一个位置
        {
            if (kk < k && pos == c[kk].p)
                now = min(now, c[kk].tem), kk++;
            pre[pos++] = now++;
        }
        kk = k - 1, pos = c[kk].p, now = c[kk].tem;
        while (pos > 0) //从倒数第一个空调的位置遍历到第一个位置
        {
            if (kk >= 0 && pos == c[kk].p)
                now = min(now, c[kk].tem), kk--;
            suf[pos--] = now++;
        }
        for (int i = 1; i <= n; i++)
            cout << min(pre[i], suf[i]) << " ";
        cout << endl;
    }
}

总结:

类似于计算前缀和后缀的思想

posted @ 2021-07-16 14:37  Wajor  阅读(90)  评论(0)    收藏  举报