“小马智行杯“第十九届广东省大学生程序设计竞赛 暨中国大学生程序设计大赛广东省赛J 新英雄

这篇博客主要讨论了一个关于游戏策略的问题,即索亚如何通过踏和斩操作,以最少的时间到达最后一列小兵。题目中给出了友方和敌方小兵的分布,并要求计算最短时间。解决方案涉及到区间合并和路径规划,需要考虑法力值限制和敌我小兵的影响。代码实现中,首先对区间进行排序,然后逐一处理,判断敌我状态并计算总时间。最终,根据题目条件输出最短时间或无法移动的特殊结果。
摘要由CSDN通过智能技术生成

J 新英雄

在这里插入图片描述

现在设计师有一个问题:假设索亚现在站在一个友方小兵上,他前面有 n 个小兵排成笔直的一队,从近到远从 1 到 n 编号,起点位置的友方小兵视为第 0 个小兵。相邻两个小兵距离为 1。小兵分为我方小兵和敌方小兵。

一开始索亚的法力值为 0。索亚可以用"踏"向前或向后移动到一个友方的相邻小兵上;或者在有法力时,用"斩"向前或向后移动到一个任意的相邻小兵上。那么索亚到最后一个小兵最短需要多少时间?

输入格式:
输入第一行两个正整数 n,m(1≤n≤1e9 ,1≤m≤1e5 )。

接下来共 m 行,每行共三个正整数 t,l,r(1≤t≤2,1≤l,r≤n)。

对于每一行,当 t=1 时,代表第 l 个到第 r 个是友方小兵;当 t=2时,代表第 l 个到第 r个是敌方小兵。保证每个整点有且只有一个小兵。

输出格式
输出共一行,如果索亚无法移动到最后一个小兵,则输出"0/21/0"(不含双引号)。
否则包含一个正整数,表示需要的最短时间。

输入样例 1:
8 2
1 1 5
2 6 8
输出样例 1:
16
输入样例 2:
8 2
1 1 1
2 2 8
输出样例 2:
28
输入样例 3:
1 1
2 1 1
输出样例 3:
0/21/0
在这里插入图片描述

先合并一下区间然后注意爆int和取整问题即可

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N= 1e5+10;
typedef long long ll;
int n,m;
struct qj{
    ll l,r;
    int flag;
    inline bool operator<(struct qj a){
        return l<a.l;
    }
}p[N],s[N];
int cnt;
int main(){
    cin>>n>>m;
    for(int i=0;i<m;i++)cin>>p[i].flag>>p[i].l>>p[i].r;
    sort(p,p+m);
      for(int i=0;i<m;i++)  
      {
        int l=p[i].l,r=p[i].r;
        int flag=p[i].flag;
        int j=i+1;
          while(j<m&&p[j].flag==flag){
            r=p[j].r;
              j++;
          }
          s[cnt++]={l,r,flag};
          i=j-1;
      }
            if(s[0].flag==2){
                puts("0/21/0");
                return 0;
            }
    ll  ans=0,fl=0;
    for(int i=0;i<cnt;i++){
     
        int l=s[i].l,r=s[i].r;
        int flag=s[i].flag;

        if(flag==1){
            ans+=(r-l+1)*3ll;
            fl+=(r-l+1);
        }
        else {
            if(fl>=(r-l+1)){
                ans+=(r-l+1);
                fl-=(r-l+1);
            }
            else {
                int u=(r-l+1-fl);
                ll lj=ceil(u/2.0)*2ll;
                ans+=lj*3ll;  
                fl+=lj;
                fl-=(r-l+1);
                ans+=(r-l+1);
            }
        }
    }
       ans-=fl/2*2; 
    cout<<ans<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值