Genshin Master (第二十届浙大城市学院程序设计竞赛) (时间戳,减法思维) 或者(离散化+差分)

发布时间 2023-04-02 16:01:36作者: VxiaohuanV

题目大意:

 

 就是这个游戏,有6个音轨, 然后用单手操作,(5个手指头)最多只能操作5个音轨的内容, 给出每一个音轨的情况, 问, 最多可以拿多少分

思路:

  • 利用扫描线, 在同一个时刻内,尽可能的拿多的分数->有多少拿多少,有6个->拿5个
  • 因此就利用减法思维: 先把6个总的分拿到 - 6个音轨同时出现的情况, 
  • 同时出现的情况, 利用 时间戳思想去解决, 等cnt=6且是结束点的时候, 就加上这一部分的和就行了,具体 看代码
#include <bits/stdc++.h>
using namespace std;
#define ri int
#define M 2000005

int n,m,k;
struct node{
    int val;
    int id;
    int po;
    bool operator <(const node &t)const
    {
        if(val==t.val) return po<t.po;
        return val<t.val;
    }
}p[M];

int vis[M];
int now=0;
int main() {

    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    long long ans=0;
    int m=0;
    for(ri k=1;k<=6;k++)
    {
        cin>>n;m+=n;
        for(ri i=1;i<=n;i++)
        {
            now++;
            cin>>p[now].val;
            
            p[now].po=1;
            p[now].id=i;
            now++;
            cin>>p[now].val;
            p[now].po=2;
            p[now].id=i;
            ans+=p[now].val-p[now-1].val+1;
        }
    }
    sort(p+1,p+1+m*2);
    int l=0;
    int cnt=0;
    for(ri i=1;i<=m*2;i++)
    {
        if(p[i].po==1)
        {
            cnt++;
            l=p[i].val;
        }else
        {
            if(cnt==6)
            {
                ans-=p[i].val-l+1;    
            }    
            cnt--;
        }
    
    }
    
    
    cout<<ans;

}
View Code

题解思路:

  • 这道题本质,就是区间覆盖问题, 看同一个时间内被多少个音轨覆盖,然后来个min(5,)
  • 但是发现数据范围很大,于是离散化处理即可.