思路:
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;
}