Codeforces Round #731 (Div. 3) E. Air Conditioners

被hack了
请移步至我队友写的题解

点我

E. Air Conditioners

题意

给定q组样例
(q <= 1e4)
每组样例给
n , k 
x1 , x2 , ..... xk
t1 , t2 , ..... tk 
( x <= 3e5 , t <= 1e9 )
( q组样例n的总和 <= 3e5)
n表示数轴上的n个点
k表一共有k个冰箱
x,t 表示该冰箱在数轴上的位置,温度为t

求对数轴上的每一个i [1 <= i <= n ]
min( t j t_j tj + ∣ x j − i ∣ \vert {x_j-i} \vert xji ) [ 1 <= j <= k ] 的值

思路

我们可以发现这个式子求的是
每个点与该冰箱的距离+该冰箱的温度
温度是不变的 于是距离可以用bfs来求

所以可以跑多起点bfs
(第一个样例的答案已经很明显在给你提示了)
如果跑的过程中发现这个点的答案可以更小
就更新,否则退出

时间复杂度:O ?

#include<bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define re register int
#define pll pair<int,int> 
#define x first 
#define y second 
#define sf(x) scanf("%d",&x)
#define sfl(x) scanf("%lld",&x)
typedef long long ll ;
using namespace std;
const int N =  1e6 + 10 , M = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
int t ;
int n , k ;
pll q[N] ; // q[i].x 表示温度  q[i].y 表示位置
int ans[N] ;  // 最后的答案数组
int main()
{
    cin >> t ;
    
    while(t--)
    {
        cin >> n >> k ;
        
        fer(i,1,n) ans[i] = inf ;
        
        fer(i,1,k) sf(q[i].y) ;
        
        fer(i,1,k) sf(q[i].x) ;
        
        queue<pll> f ;
        for(int i = 1 ; i <= k ; i ++)
        {
            f.push({q[i].y,q[i].x}) ;
            // 一维表示位置,二维表示温度
        }
        
        while(f.size())
        {
            auto t = f.front() ;
            f.pop() ;
            
            // 如果当前点的权值小于这个点的答案  就更新
            if(t.y <= ans[t.x])  
            {
                ans[t.x] = t.y ; // 更新答案
                
                if(t.x - 1 >= 1)  // 如果可以向数轴左边搜
                {
                    f.push({t.x - 1 , t.y + 1}) ;
                    //  位置 - 1 ,权值 + 1
                }
                
                if(t.x + 1 <= n)  // 如果可以向数轴右边搜
                {
                    f.push({t.x + 1 , t.y + 1}) ;
                    //  位置 + 1 ,权值 + 1
                }
            }
        }
        
        for(int i = 1 ; i <= n ; i ++) cout << ans[i] << " " ;
        
        cout << "\n" ;
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值