• AtCoder Beginner Contest 257


    D - Jumping Takahashi 2

    题目描述:

    在二维平面上有n个蹦床,每个蹦床都有一个弹力值p,你自己有一个初始的弹跳能力S,从一个点蹦到另一个点的条件是 P i ∗ S > = ∣ x i − x j ∣ + ∣ y i − y j ∣ P_i * S >= |x_i-x_j|+|y_i - y_j| PiS>=xixj+yiyj

    S最小为多少时,满足可以使得从任意一个点出发,能到达其他的任何一个点

    思路:

    根据上面那个式子,不难发现 S > = ⌈ ∣ x i − x j ∣ + ∣ y i − y j ∣ p i ⌉ S >= \lceil{\frac{|x_i-x_j|+|y_i-y_j|}{p_i}}\rceil S>=pixixj+yiyj

    我们可以根据这个,作为两个点之间的距离,跑floyed维护出最短路上的最大权值,枚举每个点为起点,找出每个点到其他点的路径的最大值,取一个最小值即可

    或者可以二分答案,然后dfs爆搜,但是这种方法我觉得复杂度太大没敢写

    #include <bits/stdc++.h>
    using namespace std;
    
    #define endl '\n'
    #define inf 0x3f3f3f3f
    #define mod 998244353
    #define m_p(a,b) make_pair(a, b)
    #define mem(a,b) memset((a),(b),sizeof(a))
    #define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
    
    typedef long long ll;
    typedef pair <int,int> pii;
    
    #define MAX 300000 + 50
    ll n, m, k, op, x;
    struct ran{
        ll x, y;
        ll p;
    }tr[MAX];
    ll dis[205][205];
    void work(){
        cin >> n;
        for(int i = 1; i <= n; ++i){
            cin >> tr[i].x >> tr[i].y >> tr[i].p;
        }
        for(int i = 1; i <= n; ++i){
            for(int j = 1; j <= n; ++j){
                dis[i][j] = (abs(tr[i].x - tr[j].x) + abs(tr[i].y - tr[j].y) + tr[i].p - 1) / tr[i].p;
            }
        }
        for(int k = 1; k <= n; ++k){
            for(int i = 1; i <= n; ++i){
                for(int j = 1; j <= n; ++j){
                    dis[i][j] = min(dis[i][j], max(dis[i][k] , dis[k][j]));
                }
            }
        }
        ll ans = 1e18;
        for(int i = 1; i <= n; ++i){
            ll cnt = 0;
            for(int j = 1; j <= n; ++j){
                cnt = max(cnt, dis[i][j]);
            }
            ans = min(ans, cnt);
        }
        cout << ans << endl;
    }
    
    
    int main(){
        io;
        work();
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    E - Addition and Multiplication 2

    题目描述:

    你现在有n元,你可以花c[i]元钱,使得当前获得的价值乘10 + i,最开始手里的价值为0,问最多能获得多大的价值

    思路:

    显然让长度尽可能长是最优的

    满足长度最长的情况下,我们再考虑选择一些不会使得长度变小,且值i更大的,贪心就行

    我们先确定结果是输出多少个数字,再去枚举每次输出哪个数字,枚举的时候从9枚举到1,判断剩余的钱减去当前的c[i]后会不会改变总的长度即可

    #include <bits/stdc++.h>
    using namespace std;
    
    #define endl '\n'
    #define inf 0x3f3f3f3f
    #define mod 998244353
    #define m_p(a,b) make_pair(a, b)
    #define mem(a,b) memset((a),(b),sizeof(a))
    #define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
    
    typedef long long ll;
    typedef pair <int,int> pii;
    
    #define MAX 300000 + 50
    int n, m, k, op, x;
    int c[10];
    void work(){
        cin >> n;
        for(int i = 1; i <= 9; ++i){
            cin >> c[i];
        }
        int minx = *min_element(c + 1, c + 10);
        k = n / minx;
        for(int i = 1; i <= k; ++i){
            for(int j = 9; j >= 1; --j){
                if(n - c[j] >= minx * (k - i)){
                    n -= c[j];
                    cout << j;
                    break;
                }
            }
        }
    }
    
    
    int main(){
        io;
        work();
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    F - Teleporter Setting

    题目描述:

    n个点,m条边,每条边的权值都是1,有一些边的端点时0,则说明这条边是不固定的

    现在需要输出n个数字,表示将所有不固定的边连接到i上去后,1到n的最短路

    思路:

    由于每次都是将所有不固定的边连接到一个相同的点上去,所以我们可以考虑建图的时候,把0作为特殊点,正常建图,然后我们跑两次bfs,分别求出以1为起点和以n为起点的时候的最短路,对于每次连接到i的情况,我们分两种情况,一种是不走那种特殊边,则答案就是1到n的最短路,另一种是走特殊边,这个时候我们可以把0看成i,分两种情况,一种是1到i,再从i到n,另一种情况是1到0,再从i到n,对这三种情况求个最小值就可以

    #include <bits/stdc++.h>
    using namespace std;
    
    #define endl '\n'
    #define inf 0x3f3f3f3f
    #define mod 998244353
    #define m_p(a,b) make_pair(a, b)
    #define mem(a,b) memset((a),(b),sizeof(a))
    #define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
    
    typedef long long ll;
    typedef pair <int,int> pii;
    
    #define MAX 300000 + 50
    int n, m, k, op, x, y;
    vector<int>G[MAX];
    int dis1[MAX];
    int dis2[MAX];
    void work(){
        cin >> n >> m;
        for(int i = 1; i <= m; ++i){
            cin >> x >> y;
            G[x].push_back(y);
            G[y].push_back(x);
        }
        mem(dis1, inf);
        mem(dis2, inf);
        queue<int>q;
        q.push(1);
        dis1[1] = 0;
        while(!q.empty()){
            int u = q.front();q.pop();
            for(auto v : G[u]){
                if(dis1[v] != inf)continue;
                dis1[v] = dis1[u] + 1;
                q.push(v);
            }
        }
        q.push(n);
        dis2[n] = 0;
        while(!q.empty()){
            int u = q.front();q.pop();
            for(auto v : G[u]){
                if(dis2[v] != inf)continue;
                dis2[v] = dis2[u] + 1;
                q.push(v);
            }
        }
        for(int i = 1; i <= n; ++i){
            int ans = min(dis1[n], min(dis1[i] + dis2[0], dis1[0] + dis2[i]));
            if(ans == inf)cout << -1 << ' ';
            else cout << ans << ' ';
        }
        cout << endl;
    }
    
    
    int main(){
        io;
        work();
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
  • 相关阅读:
    【相机坐标系、ORB_SLAM2坐标系】
    阿里云国际站服务器设置自动开关机的攻略
    锁机制之 Condition 接口
    SI314软硬件兼容替代GTX314L—低功耗14通道电容触摸传感器
    webpack5学习进阶:多页面应用、Tree Shaking、PWA、Shimming
    stm32F407学习笔记2——GPIO操作跑马灯实验
    二、常见的EDID问题
    【Linux】 ubuntu ffmpeg环境配置
    Go基础18-理解方法的本质以选择正确的receiver类型
    数据结构 | 顺序表
  • 原文地址:https://blog.csdn.net/weixin_51216553/article/details/125538490