AtCoder Beginner Contest 434 C-E 题解

C. Flapping Takahashi

题意

初始高度为 H H H,可以上下移动,要求每秒高度变化不超过 1 1 1,且高度不能为负。给定 n n n 个限制,第 i i i 个限制为在第 t i t_i ti 秒,高度必须在 l i , u i l_i,u_i li,ui 之间。问是否存在一种可行方案。

思路

对于每个限制,若上次的高度区间已经固定,就可以确定这次能否到达。若上次的时间为 p r v prv prv,区间为 l , r l,r l,r,则这次区间为 l − ( t i − p r v ) , r + ( t i − p r v ) l-(t_i-prv),r+(t_i-prv) l−(ti−prv),r+(ti−prv),判断该区间与 l i , u i l_i,u_i li,ui 是否有交集,并更新 l , r l,r l,r,使 l ← max ⁡ ( l , l i ) l\gets \max(l,l_i) l←max(l,li), r ← min ⁡ ( r , u i ) r\gets \min(r,u_i) r←min(r,ui) 即可。

现在只要知道初始的高度区间即可,显然为 H , H H,H H,H,即 l = r = H l=r=H l=r=H。

时间复杂度 O ( n ) \mathcal{O}(n) O(n)。

C++ 代码

cpp 复制代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
void solve(){
    int n,h; cin>>n>>h;
    int L=h,R=h,prv=0;
    bool fl=1;
    for(int i=1;i<=n;i++){
        int t,l,r; cin>>t>>l>>r;
        L-=(t-prv);
        R+=(t-prv);
        fl&=((R>=l&&r>=L));
        L=max(L,l);
        R=min(R,r);
        prv=t;
    }
    if(fl) cout<<"Yes\n";
    else cout<<"No\n";
}
main(){int T;cin>>T;while(T--)solve();}

D. Clouds

题意

有一个 2000 × 2000 2000\times 2000 2000×2000 的平面,有 n n n 个矩形,对于所有 1 ≤ i ≤ n 1\le i\le n 1≤i≤n,求:不被【除矩形 i i i 以外的任何矩形】覆盖的点有多少个。

思路

这题应该可以扫描线做,但是大可不必。

首先计算不去除任何矩形不覆盖的点的个数 a n s ans ans。然后考虑去除矩形 i i i 的贡献。我们发现,去除矩形 i i i 会增加不覆盖的点个数,当且仅当这个点仅被这一个矩形覆盖。所以我们可以对矩形覆盖位置做一个二维差分,记录那些位置只被覆盖一次,然后覆盖这个位置的矩形的贡献就加一。最后对于每个矩形的贡献 r e s i res_i resi,答案即为 a n s + r e s i ans+res_i ans+resi。

C++ 代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=2005;
int a[N][N],cnt[N][N],cf[N][N],res[200005];
main(){
    int n; cin>>n;
    for(int i=1;i<=n;i++){
        int u,d,l,r; cin>>u>>d>>l>>r;
        cnt[u][l]++; cnt[u][r+1]--; cnt[d+1][r+1]++; cnt[d+1][l]--;
        cf[u][l]+=i; cf[u][r+1]-=i; cf[d+1][r+1]+=i; cf[d+1][l]-=i; //差分记录覆盖它的id,若仅被覆盖一次,此值必为覆盖它的矩形编号
    }
    int ans=0;
    for(int i=1;i<=2000;i++){
        for(int j=1;j<=2000;j++){
            cnt[i][j]+=cnt[i-1][j]+cnt[i][j-1]-cnt[i-1][j-1];
            cf[i][j]+=cf[i-1][j]+cf[i][j-1]-cf[i-1][j-1];
            ans+=(cnt[i][j]==0);
            if(cnt[i][j]==1) res[cf[i][j]]++;
        }
    }
    for(int i=1;i<=n;i++) cout<<ans+res[i]<<endl;
    return 0;
}

E. Distribute Bunnies

题意

数轴上有 n n n 只兔子,第 i i i 只兔子要么站在 X i + R i X_i+R_i Xi+Ri,要么站在 X i − R i X_i-R_i Xi−Ri。问 n n n 只兔子位置的集合去重后的大小最大为多少?

思路

建图。把 X i − R i X_i-R_i Xi−Ri 和 X i + R i X_i+R_i Xi+Ri 连边(注意要把点离散化),问题转化为对于每条边,把其中一个端点涂黑,最多能涂黑多少个点。

考虑每个连通块,若大小为 s z sz sz。

  • 若该连通块为一棵树,显然可以任意一点为根,每条边都涂黑深度较大的那个点,最终只剩下根节点,所以可以涂黑 s z − 1 sz-1 sz−1 个点。
  • 若该连通块为一棵基环树,可以以环为根,每条边都涂黑深度较大的那个点,最终只剩下环上的点,显然环上的点可以都涂黑。所以可以涂黑 s z sz sz 个点。
  • 若该连通块为一个无特殊性质的连通图,可以找到任意一棵生成树,再加一条边变为基环树,转化为上述情形,可以涂黑 s z sz sz 个点。

最终结论,不能涂黑的点数即为树的个数,答案即为总点数减去树的个数。

时间复杂度 O ( n log ⁡ n ) \mathcal{O}(n\log n) O(nlogn),瓶颈在离散化。

C++ 代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n;
map<int,int> mp;
vector<int> g[N<<1];
bool used[N<<1];
int vcnt=0,edgecnt=0;
void dfs(int u){
    used[u]=1;
    vcnt++;
    for(int v:g[u]){
        edgecnt++;
        if(!used[v]){
            dfs(v);
        }
    }
}
int32_t main(){
    int n; cin>>n;
    int cnt=0;//总点数
    for(int i=1;i<=n;i++){
        int x,r; cin>>x>>r;
        int a=x-r,b=x+r;
        if(!mp[a]) mp[a]=++cnt;
        if(!mp[b]) mp[b]=++cnt;
        g[mp[a]].push_back(mp[b]);
        g[mp[b]].push_back(mp[a]);
    }
    int ans=cnt;
    for(int i=1;i<=cnt;i++){
        if(!used[i]){
            vcnt=edgecnt=0;
            dfs(i);
            ans-=(edgecnt/2==vcnt-1);//edgecnt/2 为实际边数,若边数==点数-1,该图为一棵树
        }
    }
    cout<<ans<<endl;
    return 0;
}
相关推荐
我是海飞18 分钟前
杰理JL703N SSD1306 OLED(128x64) 点阵屏移植说明
单片机·算法·嵌入式·音频·杰理
wabs6661 小时前
关于图论【最短路径之Bellman_ford 算法(单源有限最短路)|卡码网96.城市间货物运输III的思考】
数据结构·算法·图论·卡码网·bellman_ford·单源有限最短路
会周易的程序员2 小时前
aiDgePLC — IEC61131-3 ST PLC 虚拟机调试与运行环境
c++·物联网·虚拟机·st·工业协议·iec61131·梯形图
lsylalalala3 小时前
常见的排序算法1
数据结构·算法·排序算法
想吃火锅10054 小时前
【leetcode】54. 螺旋矩阵
算法·leetcode·矩阵
wuminyu4 小时前
JVM利用io_uring优化堆外内存性能原理剖析
java·linux·c语言·jvm·c++
gumichef4 小时前
第二章:C/C++内存管理
c++·内存管理
想吃火锅10054 小时前
【leetcode】300. 最长递增子序列
算法·leetcode·职场和发展
imaol14 小时前
数据结构---队列
java·数据结构·算法
数模竞赛Paid answer4 小时前
2026年电工杯数学建模A题绿电直连型电氢氨园区优化运行求解全过程论文及程序
算法·数学建模·电工杯