HDU 5203 Rikka with wood sticks

题目要求分成4段 即只能砍3刀 而令其中的3部分不含有不牢固的小木棍 所以所有的不牢固的小木棍都应该唯一同一段 而为了优先满足3段和长度最大 应该使包含不牢固的小木棍的那一段长度尽量短 即应该沿着不牢固的小木棍中编号最大和最小的2个小木棍切2刀 剩下的2段或1段 在计算个数

2段(设为a,b)分成3条边时 只能把较长的a边切开,切开后的2部分a1和a2和大于b了 只要在满足 abs(a1-a2)<b即可 由此可推出a1的上下界 就可以O(1)的算出答案

而对于1段分成3条边时 先将其分成2段 通过枚举其中一段的长度 算出另一段 再带入前面的公式即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#define scnaf scanf
#define cahr char
#define bug puts("bugbugbug");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int mod=1e9+7;
const int maxn=1e6+100;
const int inf=1e9;
ll go(ll a);
ll go2(ll a,ll b)
{
    if(a==b) return 0;
    if(a>b)swap(a,b);
    if(a==0) return go(b);
    ll l=(b-a)/2+1;
    ll r=b-l;
    return max(r-l+1,(ll)0);
}
ll go(ll a)
{
    ll ans=0;
    for(int i=1;i<a;i++)
    {
      int j=a-i;
      if(i>j)break;
      ans+=go2(i,j);
    }
    return ans;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        ll ans=0;
        int maxx=-1,minn=n+1;
        for(int i=0;i<m;i++){
            int b;
            scanf("%d",&b);
            maxx=max(maxx,b);
            minn=min(minn,b);
        }
        if(maxx==-1)  ans=go(n);
        else  ans=go2(minn-1,n-maxx);
        printf("%lld\n",ans);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值