AtCoder Beginner Contest 153 F - Silver Fox vs Monster

题目链接 https://atcoder.jp/contests/abc153/tasks/abc153_f

题意 : 在坐标轴上有一些怪兽,每个怪兽有对应的生命值hi,你可以对他们进行炮击,你的每次炮击可以队该点前后D范围内的怪兽造成A的伤害,问最少要炮击多少次。

我的最初的想法是先排序,扫到最左边的怪兽,先进行炮击,把他打死,然后记录炮击了多少次,然后把其后2d距离的怪兽都炮击一下发现超时

代码如下:

inline ll read(){
   ll s=0,w=1;
   char ch=getchar();
   while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)w=-1;ch=getchar();}
   while(ch>=‘0‘&&ch<=‘9‘) s=s*10+ch-‘0‘,ch=getchar();
   return s*w;
}
const int N = 2e5+5;
struct mon
{
        ll x,h;
};
mon monster[N];
bool cmp(mon a, mon b)
{
    return a.x < b.x;
}
int main()
{
    //ios::sync_with_stdio(false);cin.tie(NULL);
    ll n, d, a;
    n = read();
    d = read();
    a = read();
    for (int i = 0; i < n; i++)
    {
        monster[i].x = read();
        monster[i].h= read();
    }
    sort(monster, monster + n,cmp);
    ll ans = 0;
    for (int i = 0; i < n; i++)
    {
        if (monster[i].h>0)
        {
            ll xx = monster[i].x + d;
            ll num = (monster[i].h + a - 1) / a;
            ans += num;
            monster[i].h = 0;
            bool flag = false;
            for (int j = i + 1; monster[j].x >= (xx - d) && monster[j].x<= xx + d && j < n;j++)
            {
                monster[j].h-=a*num;

            }
        }
    }
    cout << ans << endl;

}

后来学习了大佬的代码,他是这么操作的,建立一个数组c[i],记录每个点已经炮击了几次need,则c[i] += need,下一个点已经炮击的次数就是c[i + 1] += c[i],因为范围外就无效,所以每个点i你要先找到他最远能打到哪里,然后要事先减掉need,即c[j] -= need; 这样,当i到了j-1时,执行c[i+1] += c[i], need正好抵消,我觉得这个技巧太妙了

代码:

#include<iostream>
#include<string>
#include <cstdlib>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include <iomanip>

// #pragma comment(linker, "/STACK:1024000000,1024000000")
// #define pi acos(-1)
// #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x7f7f7f7f //2139062143
#define INF1 0x3f3f3f3f //1061109567
#define INF2 2147483647
#define llINF 9223372036854775807
#define pi 3.141592653589793//23846264338327950254
#define pb push_back
#define ll long long
#define debug cout << "debug\n";
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
// ios::sync_with_stdio(false);cin.tie(NULL);
#define scai(x) scanf("%d", &x)
#define sca2i(x, y) scanf("%d %d", &x, &y)
#define scaf(x) scanf("%lf", &x)
#define sca2f(x, y) scanf("%lf %lf", &x, &y)
#define For(m,n) for (int i = m;  i < n; i++)

#define local
#ifdef local
#endif

#define MAX 10233
#define LCH(i) ((i) << 1)
#define RCH(i) ((i) << 1 | 1)
inline ll read(){
   ll s=0,w=1;
   char ch=getchar();
   while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)w=-1;ch=getchar();}
   while(ch>=‘0‘&&ch<=‘9‘) s=s*10+ch-‘0‘,ch=getchar();
   return s*w;
}
const int N = 2e5+5;
ll c[N];
struct mon
{
        ll x,h;
};
mon monster[N];
bool cmp(mon a, mon b)
{
    return a.x < b.x;
}
int main()
{
    //ios::sync_with_stdio(false);cin.tie(NULL);
   // cout << 50ll << endl;
    ll n, d, a;
    n = read();
    d = read();
    a = read();
    for (int i = 0; i < n; i++)
    {
        monster[i].x = read();
        monster[i].h= read();
    }
    sort(monster, monster + n,cmp);
    ll ans = 0;
    for (int i = 0,j = 0; i < n; i++)
    {
        while(j < n && monster[j].x <=monster[i].x + 2*d)
            ++j;
        ll need = max((monster[i].h - c[i]*a + a - 1)/a, 0ll);
        ans += need;
        c[i] += need;
        c[j] -= need;
        c[i+1] += c[i];
    }
    cout << ans << endl;

}

原文地址:https://www.cnblogs.com/hulian425/p/12236097.html

时间: 2024-11-06 12:30:28

AtCoder Beginner Contest 153 F - Silver Fox vs Monster的相关文章

AtCoder Beginner Contest 152 - F - Tree and Constraints (容斥定理+树上路径的性质)

AtCoder Beginner Contest 152 - F - Tree and Constraints (容斥定理+树上路径的性质) We have a tree with NN vertices numbered 11 to NN. The ii-th edge in this tree connects Vertex aiai and Vertex bibi. Consider painting each of these edges white or black. There ar

AtCoder Beginner Contest 132 F - Small Products

数 sqrt 缩小范围 整除分块 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <iostream> 8 using namespace std; 9 #define ll long long 10 1

AtCoder Beginner Contest 133 F - Colorful Tree

题意:给出一棵n个点的树,每条边有颜色和边长两个属性,n个询问,每次询问把颜色x的边的边长变为y问u到v的路径长度是多少,询问之间独立. 解法:这道题蛮有意思的.解法参考https://www.cnblogs.com/Tieechal/p/11185912.html这位大佬的,这里说下我的理解. 对于每组询问(x,y,u,v)答案比较显然就是dist(u,v)+(sumlen[x]-sumcnt[x]*y),但是这道题在线不好做我们考虑离线做.但是答案的式子是设计到两个点的,怎么才能离线做呢?这

AtCoder Beginner Contest 128 F - Frog Jump

题意 有一只青蛙,有\(0, 1, \cdots, N - 1\)个荷叶.每个荷叶上有权值\(s_i\). 选定\(A\), \(B\),初始分数为\(0\). 当前位置为\(x\): 对于\(y = x + A\): 如果\(y = N - 1\),游戏结束. 如果\(y \neq N - 1\),但是\(y\)这个荷叶存在,那么分数增加\(s_i\),并且这片荷叶消失. 如果\(y \neq N - 1\),但是\(y\)这个荷叶不存在,那么分数减去\(10^{100}\),游戏结束. 对于

AtCoder Beginner Contest 136

AtCoder Beginner Contest 136 Contest Duration : 2019-08-04(Sun) 20:00 ~ 2019-08-04(Sun) 21:40 Website: AtCoder BC-136 后面几题都挺考思考角度D. C - Build Stairs 题目描述: 有n座山从左到右排列,给定每一座山的高度\(Hi\),现在你可以对每座山进行如下操作至多一次:将这座山的高度降低1. 问是否有可能通过对一些山进行如上操作,使得最后从左至右,山的高度呈不下降

AtCoder Beginner Contest 154 题解

人生第一场 AtCoder,纪念一下 话说年后的 AtCoder 比赛怎么这么少啊(大雾 AtCoder Beginner Contest 154 题解 A - Remaining Balls We have A balls with the string S written on each of them and B balls with the string T written on each of them. From these balls, Takahashi chooses one

AtCoder Beginner Contest 155 简要题解

AtCoder Beginner Contest 155 A:签到失败,WA一次. int main() { int a, b, c; cin >> a >> b >> c; if(a == b && b == c) cout << "No"; else if(a == b || a == c || b == c) cout << "Yes"; else cout << &quo

【ATcoder】AtCoder Beginner Contest 161 题解

题目链接:AtCoder Beginner Contest 161 原版题解链接:传送门 A - ABC Swap 这题太水,直接模拟即可. 1 #include <iostream> 2 using namespace std; 3 int main() { 4 int a, b, c; 5 cin >> a >> b >> c; 6 swap(a, b); 7 swap(a, c); 8 cout << a << " &

AtCoder Beginner Contest 103 D(贪心)

AtCoder Beginner Contest 103 D 题目大意:n个点,除第n个点外第i与第i+1个点有一条边,给定m个a[i],b[i],求最少去掉几条边能使所有a[i],b[i]不相连. 按右端点从小到大排序,如果当前选的去掉的边在区间内,那么符合条件,否则ans++,并贪心地把去掉的边指向右端点,因为前面的区间都满足条件了,所以要去掉的边要尽量向右移使其满足更多的区间. 1 #include <iostream> 2 #include <cstdio> 3 #incl