洛谷U3348 A2-回文数

U3348 A2-回文数

题目背景

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

题目描述

求从小到大第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,末位-1,然后进行对称变换
    细节有三个:
    1.如果前两项为10,需要把1减去,0变成9
    2.如果末项为9,加1之后向前进位
    3.对称变换需要考虑对称轴是最后一位数还是最后一位数后面的位置,这就需要提前预处理输出结果一共有几位数
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long sum[60],a[60];
long long n;
int bin[1000],len,b[1000];
long long pow(int mi){
    long long res=1;
    for(int i=1;i<=mi;i++)res*=10;
    return res;
}
int main(){
    freopen("hws.in","r",stdin);
    freopen("hws.out","w",stdout);
    for(int i=1;i<=37;i++){
        int mi=((i+1)/2-1);
        a[i]=1LL*9*pow(mi);
        sum[i]=sum[i-1]+a[i];
    }
    cin>>n;
    int pos=lower_bound(sum+1,sum+38,n)-sum;//pos就是数的位数
    if(n==sum[pos-1])pos--;
    //cout<<pos<<endl;
    while(n){
        b[++len]=n%10;
        n/=10;
    }
    for(int i=1,j=len;i<=len;i++,j--)bin[i]=b[j];
    bin[1]--;bin[len]++;
    if(bin[1]==0&&bin[2]==0)bin[2]=9;
    int now=len;
    while(bin[now]>=10){
        bin[now-1]+=bin[now]/10;
        bin[now]%=10;
        now--;
    }
    int l=len,r=len+1;
    if(pos%2==1)l--;
    while(l>=1){
        bin[r]=bin[l];
        l--;r++;
    }
    l=1,r--;
    while(bin[l]==0)l++;
    while(bin[r]==0)r--;
    for(int i=l;i<=r;i++)printf("%d",bin[i]);
}
时间: 2024-08-27 19:23:06

洛谷U3348 A2-回文数的相关文章

洛谷——P1609 最小回文数

题目描述 回文数是从左向右读和从右向左读结果一样的数字串. 例如:121.44 和3是回文数,175和36不是. 对于一个给定的N,请你寻找一个回文数P,满足P>N. 满足这样条件的回文数很多,你的任务是输出其中最小的一个. 输入输出格式 输入格式: 1行,一个正整数N.N的数值小于10^100,并且N没有前导0. 输出格式: 你的程序应该输出一行,最小的回文数P(P>N). 输入输出样例 输入样例#1: 复制 44 输出样例#1: 复制 55 说明 50%的数据,N<10^9 100%

洛谷 P1207 [USACO1.2]双重回文数 Dual Palindromes

题目描述 如果一个数从左往右读和从右往左读都是一样,那么这个数就叫做"回文数".例如,12321就是一个回文数,而77778就不是.当然,回文数的首和尾都应是非零的,因此0220就不是回文数. 事实上,有一些数(如21),在十进制时不是回文数,但在其它进制(如二进制时为10101)时就是回文数. 编一个程序,从文件读入两个十进制数N (1 <= N <= 15)S (0 < S < 10000)然后找出前N个满足大于S且在两种或两种以上进制(二进制至十进制)上是

洛谷 P1015 回文数 Label:续命模拟QAQ

题目描述 若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数. 例如:给定一个10进制数56,将56加65(即把56从右向左读),得到121是一个回文数. 又如:对于10进制数87: STEP1:87+78 = 165 STEP2:165+561 = 726 STEP3:726+627 = 1353 STEP4:1353+3531 = 4884 在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884. 写一个程序,给定一个N(2<=N<=10,N=1

洛谷P1207 [USACO1.2]双重回文数 Dual Palindromes

P1207 [USACO1.2]双重回文数 Dual Palindromes 291通过 462提交 题目提供者该用户不存在 标签USACO 难度普及- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 如果一个数从左往右读和从右往左读都是一样,那么这个数就叫做“回文数”.例如,12321就是一个回文数,而77778就不是.当然,回文数的首和尾都应是非零的,因此0220就不是回文数. 事实上,有一些数(如21),在十进制时不是回文数,但在其它进制(如二进制时为10101)时就是回文数. 编

洛谷 U3348 A2-回文数

题目背景 方方方很喜欢回文数,于是就有了一道关于回文数的题目. 题目描述 求从小到大第n(1<=n<=10^18)个回文数. 注释:出题人认为回文数不包括0. 输入输出格式 输入格式: 一行一个正整数n. 输出格式: 第n个回文数. 输入输出样例 输入样例#1: 2333 输出样例#1: 1334331 输入样例#2: 12345678987654321 输出样例#2: 23456789876543222234567898765432 说明 对于50%的数据,n<=3000. 对于100

洛谷 P1015 回文数

P1015 回文数 标签 字符串 模拟 NOIp普及组 1999 云端 难度 普及- 时空限制 1s / 128MB 题目描述 若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数. 例如:给定一个10进制数56,将56加65(即把56从右向左读),得到121是一个回文数. 又如:对于10进制数87: STEP1:87+78 = 165 STEP2:165+561 = 726 STEP3:726+627 = 1353 STEP4:1353+3531 = 4884 在这里的一

实验二 (二) 判断回文数

(2)编写一个Java应用程序.用户从键盘输入一个1—9999之间的数,程序将判断这个数是几位数,并判断这个数是否是回文数.回文数是指将该数含有的数字逆序排列后得到的数和原数相同,例如12121.3223都是回文数. 如何从键盘输入一个数呢? 1 package test; 2 import java.util.Scanner; 3 public class KeyboardInput { 4 public static void main(String[] args){ 5 Scanner x

c语言练习3——判断一个5位数是否回文数

#include<stdio.h> #include<stdlib.h> /*题目:判断一个五位数是否为回民数.*/ int main(){ int a,a1,a2,a3,a4,a5; while(1){ printf("请输入一个5位数:"); scanf("%d",&a); a1=a%10; a2=a/10%10; a3=a/100%10; a4=a/1000%10; a5=a/10000; if(a1==a5&&

判断一个数是否为回文数

#include <stdio.h> int is_palindromic(int num) {  char _old = num;  char _new = 0;  while (num)  {   _new = _new * 10 + (num % 10);   num = num / 10;  }  if (_new == _old)  {   return 1;  }  else  {   return 0;  } } int main() {  int num = 0;  scanf