Codeforces 899D Shovel Sale

题意:
给一个数n(2<=n<=1e9),从1到n中选两个数字相加,得到n*(n-1)/2个结果,假设这些结果中末尾包含连续的9最多是x个,问这些结果中末尾包含连续x个9的数有多少个,即有多少种组合(x,y),(其中1<=x<=n,1<=y<=n,x!=y),x+y末尾包含连续x个9,其中(x,y)和(y,x)被视为同一种组合。
题解:
令sum代表n+n-1,如果sum是99999...99这种形式的话,则答案是1。
如果不是,假设sum有len位,则x是len-1,x是上面提到的x。则此时枚举最高为从0到8,分别得到09999..9,19999..9,29999...9。。。。。89999...9。令这些数是p。
如果p<=n+1,则有(p-1)/2种方案,这个很显然。。。
如果p>n+1&&p<=n+n-1,则有(2*n-p+1)/2种方案。这里说明一下,因为最大数是n,如果要组合成p的话,且p是大于n+1的,所以要求最小的数是p-n。则从p-n到n一共有n-(p-n)+1个数。再除以2就是方案数。
否则如果p>n+n-1,对答案无贡献。
对于n<=10的情况下,可以直接暴力。此时x最多是1。需要注意的是,如果任意的(x,y)的和末尾都没有9,则x是0,则所有组合都满足情况,答案是n*(n-1)/2。
某个步骤会爆int,所以用long long。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=100;
const int INF=0x3f3f3f3f;
typedef long long ll;

int main()
{
 //   freopen("input.txt","r",stdin);
 //   freopen("output.txt","w",stdout);

    int len=0;
    ll n,x,sum,t=1ll;
    cin>>n;
    sum=n+n-1;

    x=sum;
    while(x)
    {
        len++;
        x/=10;
        t*=10;
    }

    if(sum==t-1) cout<<"1\n";
    else if(n<=10)
    {
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                if((i+j)%10==9) ans++;
            }
        }
        if(ans!=0) cout<<ans<<endl;
        else cout<<n*(n-1)/2<<endl;
    }
    else
    {
        ll ans=0;
        t/=10;
        ll temp=t-1;
        for(int i=0;i<=8;i++)
        {
            ll nt=t*i;
            ll p=nt+temp;
            if(p<=n+1) ans+=(p-1)/2;
            else if(p>n+n-1) ;
            else ans+=(2*n-p+1)/2;
        }
        cout<<ans<<endl;
    }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值