左半部分和右半部分完全一样的特别数字 满分题解

2.特别数字


思路:
1.查看评分标准中n 的最大值达到了1e18,则一般的暴力算法会超时。
2.总结特别数字的规律,发现当n在0-1000之间时,满足的数字有9个,即11、22、33、44、55、66、77、88、99;当n在1000-10000之间时,满足的数据有90个,即9*10;同理,当n在更高的位数时也有相同的规律。
3.当数字位数为奇数时,不是特别数字,直接跳过。
4.当数字位数为偶数时,可以利用2.中的规律进行判断。


举例:
123456为六位数,通过2.规律可得其在0-10000之间的特别数字有99个;通过3.规律在10000-100000之间的特别数字为0个;现在判断100000-123456之间的特别数字,即判断左边部分100-123与右边部分100-456之间存在的组合情况:即100100、101101、102102…共24个,则最终答案为9+90+24=123个


具体代码如下:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long n;cin>>n;
    int a[10]={9,90,900,9000,90000,900000,9000000,90000000,900000000};
    //a[n]用于先前操作
    //如果n为三位数,则a[0]=9;即11、22、33、44、55、66、77、88、99
    //如果n为五位数,则a[1]=90;类似上面
    int i=0;//统计n的位数
    long t=n;
    int answer=0;//用来输出答案
    while(t!=0)
    {
        i++;
        t=t/10;
    }
    for(int j=2;j<=i-1;j+=2)
    {
        answer+=a[j/2-1];//根据n的位数加上对应的值,例如当n=123时,i=3,则answer加上a[0]=9,再进行后续操作;
    }
    //后续操作
    if(i%2==1)cout<<answer<<endl;//当n为位数为奇数,则此时answer值即为所求答案。
    //当n的位数为偶数时
    else
    {
        int k=1;
        for(int j=1;j<=i/2;j++)
        {
            k*=10;
        }
        int a=n/k;//a即为n的左半部分
        int b=n%k;//b即为n的右半部分
        k=k/10;
        if(a>b)
            answer+=a-k;//a>b,不需要+1;
        else
            answer+=a+1-k;//a<b,需要+1;
        cout<<answer<<endl;
    }
    return 0;
}
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值