洛谷 U3348 A2-回文数

本文介绍了一个求解第N个回文数的问题,并提供了一种高效的算法实现。通过分析回文数的规律,利用预计算的方式找到特定位置上的回文数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目背景

方方方很喜欢回文数,于是就有了一道关于回文数的题目。

题目描述

求从小到大第n(1<=n<=10^18)个回文数。

注释:出题人认为回文数不包括0。

输入输出格式

输入格式:

 

一行一个正整数n。

 

输出格式:

 

第n个回文数。

 

输入输出样例

输入样例#1:
2333
输出样例#1:
1334331
输入样例#2:
12345678987654321
输出样例#2:
23456789876543222234567898765432

说明

对于50%的数据,n<=3000。

对于100%的数据,1<=n<=10^18。..

 

打表找规律 

1 2 3 4 5 6位的回文个数分别是 9 9 90 90 900 900...

规律很明显了。

一个回文数 123456654321 左右是一样的

所以只求一半就可以了 然后拼接起来

屠龙宝刀点击就送

#include <cstring>
#include <cstdio>
typedef long long LL;
struct node
{
    int a[50],len;
    node()
    {
        memset(a,0,sizeof(a));len=0;
    }
}Ret,RetS;
node findhws(LL n)
{
    LL ret,cnt=0,w=0,num=9,half=1;
    for(;1;)
    {
        if(w>0&&w%2==0) num*=10;
        w++;
        if(cnt+num>=n) break;
        cnt+=num;
    }
    n=n-cnt-1;
    for(int i=1;i<=w-1>>1;++i) half*=10;//赵基数
    half+=n;
    ret=half;
    if(w%2==1) half/=10;
    for(;ret;ret/=10) Ret.a[++Ret.len]=ret%10;
    RetS=Ret;
    for(int i=1;i<=RetS.len;++i) Ret.a[RetS.len-i+1]=RetS.a[i];
    for(;half;half/=10) Ret.a[++Ret.len]=half%10;
    return Ret;
}
LL n,len;
int main()
{
    scanf("%lld",&n);
    node ans=findhws(n);
    for(int i=1;i<=ans.len;++i) printf("%d",ans.a[i]);
    return 0;
}

 

转载于:https://www.cnblogs.com/ruojisun/p/7527693.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值