回文可以分为回文数和回文字符串,后期我们会有回文字符串的题目。
回文数是一种数字。如:98789, 这个数字正读是98789,倒读也是98789,正读倒读一样,所以这个数字就是回文数。
一个回文数,它同时还是某一个数的平方,这样的数字叫做平方回数。例如:121。100 以上至1000以内的平方回数只有3个,分别是:121、484、676。
有人发现:如果给一个自然数,加上它的倒叙数(就是把它的数字顺序倒过来组成的数),再对所得的和重复这个步骤,一般说来,经过有限次计算,就会得到一个回文数。如:29+92=121 还有 194+491=685,586+685=1271,1271+1721=2992(但是,196目前还不确定)
请看以下式子:3×51=153 6×21=126 4307×62=267034 9×7×533=33579 上面这些算式,等号左边是两个(或三个)因数相乘,右边是它们的乘积。如果把每个算式中的“×”和“=”去掉,那么,它们都变成回文数,所以,我们不妨把这些算式叫做“回文算式”。
还有一些回文算式,等号两边各有两个因数。请看: 12×42=24×21 34×86=68×43 102×402=204×201 1012×4202=2024×2101 不知你是否注意到,如果分别把上面的回文算式等号两边的因数交换位置,得到的仍是一个回文算式,比如:分别把“12×42=24×21”等号两边的因数交换位置,得到算式是: 42×12=21×24 这仍是一个回文算式。
还有更奇妙的回文算式,请看: 12×231=132×21(积是2772) 12×4032=2304×21(积是48384) 这种回文算式,连乘积都是回文数。
四位的回文数有一个特点,就是它决不会是一个质数。设它为abba,那它等于a*1000+b*100+b*10+a,1001a+110b。能被11整除。
六位的也一样,也能被11整除。
还有,人们借助电子计算机发现,在完全平方数、完全立方数中的回文数,其比例要比一般自然数中回文数所占的比例大得多。例如11^2=121,22^2=484,7^3=343,11^3=1331,11^4=14641……都是回文数。
484是22的平方,同时还是121的4倍。
676是26的平方,同时还是169的4倍。
【问题描述】
输入一个正整数 n,求 1~n 之间“回文数”的个数。回文数是指一个数倒过来和原数一样,如 12121、11、1221、1 是回文数,而 1231 不是回文数。
【输入格式】
一行一个正整数 n,1≤n≤10000。
【输出格式】
一行一个正整数,表示 1~n 之间回文数的个数。
【输入样例】
12
【输出样例】
10
#include<bits/stdc++.h>
using namespace std;
bool is(int n){
int n1=n,n2=0;
while(n>0) {
n2=n2*10+n%10;
n/=10;
}
return n1==n2;
}
int main(){
int n;
cin>>n;
int cnt=0;
for(int i=1;i<=n;++i){
if(is(i))cnt++;
}
cout<<cnt;
return 0;
}
卡卡西和小朋友们把购买的图书和文具一起邮寄给了山区的贫困孩子,他们做了一件极其有意义的事情,心理乐开了花;哼着歌儿他们做起了数字游戏,他们发现有些自然数例如 131、1221 等具有左右对称的特点,这样的数被称为回文数;还有一些数如 13、17 等只能被 1 和其自身整除,这样的数被称为素数。作为编程的爱好者,卡卡西想写出一个程序,迅速求出两个数 m 和 n 之间即是回文数又是素数的个数。
【输入格式:】
输入数据只有一行包含用空格分隔的两个正整数 m 和 n
【输出格式:】
一个整数,m 和 n 之间(包含 m 和 n)即是回文数又是素数的个数。样例 1:
【输入样例:】
100 200
【输出样例:】
5
【数据范围:】
100≤m≤n≤100000
#include<bits/stdc++.h>
using namespace std;
bool sushu(int n){
for(int i=2;i*i<=n;i++){
if(n%i==0)return 0;
}
return 1;
}
bool huiwen(int m){
int tmp=m,fan=0;
while(m!=0){
fan=fan*10+m%10;
m=m/10;
}
if(fan==tmp)return 1;
else return 0;
}
int main(){
int m,n;
int ans=0;
cin>>m>>n;
for(int i=m;i<=n;i++){
if(huiwen(i)&&sushu(i))ans++;
}
cout<<ans;
return 0;
}
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。例如:给定一个十进制数 56,将 56 加 65(即把 56 从右向左读),得到 121 是一个回文数。
又如:数87:
STEP1:87+78=165
STEP2:165+561=726
STEP3:726+627=1353
STEP4:1353+3531=4884
在这里的一步是指进行了一次加法,上例最少用了 4 步得到回文数 4884。
写一个程序,给定一个数M,求最少经过几步可以得到回文数。如果在 30 步以内(包含 30 步)不可能得到回文数,则输出 Impossible!。
【输入格式】
一个整数M(0<M<10^12)。
【输出格式】
如果能在 30 步以内得到回文数,输出步数
否则输出 Impossible!。
【输入样例】
87
【输出样例】
4
#include<bits/stdc++.h>
using namespace std;
long long dz(long long x){
long long r=0;
while(x){
r=r*10+x%10;
x/=10;
}
return r;
}
int main(){
long long n,tot=0;
cin>>n;
while(n!=dz(n)){
n=n+dz(n);
tot++;
}
if(tot<=30)printf("%d",tot);
else cout<<"Impossible!";
return 0;
}
在日常生活中,通过年、月、日这三个要素可以表示出一个唯一确定的日期。
牛牛习惯用8位数字表示一个日期,其中,前4位代表年份,接下来2位代表月 份,最后2位代表日期。显然:一个日期只有一种表示方法,而两个不同的日期的表 示方法不会相同。
牛牛认为,一个日期是回文的,当且仅当表示这个日期的8位数字是回文的。现 在,牛牛想知道:在他指定的两个日期之间包含这两个日期本身),有多少个真实存 在的日期是回文的。
一个8位数字是回文的,当且仅当对于所有的i ( 1 <=i<= 8 )从左向右数的第i个 数字和第9-i个数字(即从右向左数的第i个数字)是相同的。
例如:
•对于2016年11月19日,用8位数字20161119表示,它不是回文的。
•对于2010年1月2日,用8位数字20100102表示,它是回文的。
•对于2010年10月2日,用8位数字20101002表示,它不是回文的。
每一年中都有12个月份:
其中,1、3、5、7、8、10、12月每个月有31天;4、6、9、11月每个月有30天;而对于2月,闰年时有29天,平年时有28天。
一个年份是闰年当且仅当它满足下列两种情况其中的一种:
1.这个年份是4的整数倍,但不是100的整数倍;
2.这个年份是400的整数倍。
例如:
•以下几个年份都是闰年:2000、2012、2016。
•以下几个年份是平年:1900、2011、2014。
【输入描述 】
输入包括两行,每行包括一个8位数字。
第一行表示牛牛指定的起始日期。
第二行表示牛牛指定的终止日期。
保证date_i和都是真实存在的日期,且年份部分一定为4位数字,且首位数字不为0。
保证date1 —定不晚于date2。
【输出描述】
输出一行,包含一个整数,表示在date1和date2之间,有多少个日期是回文的。
【样例输入1】
20110101
20111231
【样例输出1】
1
【样例输入2】
20100101
20101231
【样例输出2】
1
数据范围及提示
【样例说明】
对于样例1,符合条件的日期是20111102。
对于样例2,符合条件的日期是20011002和20100102。
【子任务】
对于60%的数据,满足date1 = date2。
样例解释
提示:
枚举后面四位(月份+日期)会更快。
枚举后四位然后求出整个日期,判断是否在范围内即可。
2月不需要判断是否是闰年,因为0229反过来是9220,整个日期是92200229,而9220年是闰年。
#include <bits/stdc++.h>
using namespace std;
int a,b,t[13]={0,31,28,31,30,31,30,31,31,30,31,30,31},sum;
bool hui(int x){
int x1,s=0;
x1=x;
while(x1>0){
s=s*10+x1%10;
x1/=10;
}
return s==x;
}
int z(int x){
int x1,s=0;
x1=x;
while(x1>0){
s=s*10+x1%10;
x1/=10;
}
return s%10000;
}
bool f(int x){
if(x%100==0||x%400!=0)return 0;
if(x%4==0) return 1;
return 0;
}
int main(){
cin>>a>>b;
if(a/10000==b/10000&&z(a)<=b%10000){
cout<<1;
return 0;
}
if(a==b && hui(a)==1){
cout<<1;
return 0;
}
if(a==b && hui(a)==0){
cout<<0;
return 0;
}
for(int i=a/10000;i<=b/10000;i++){
for(int j=1;j<=12;j++){
if(i==a/10000 && j==a/100%100){
if(j==2 && f(i)==1){
for(int k=1;k<=29;k++){
if(k>=a%100 && hui(i*10000+j*100+k)==1) sum++;
}
}
else{
for(int k=1;k<=t[k];k++){
if(k>=a%100 && hui(i*10000+j*100+k)==1) sum++;
}
}
}
if(i==b/10000 && j==b/100%10){
if(j==2 && f(i)==1){
for(int k=1;k<=29;k++){
if(k<=b%100 && hui(i*10000+j*100+k)==1) sum++;
}
}
else{
for(int k=1;k<=t[k];k++){
if(k<=b%100 && hui(i*10000+j*100+k)==1) sum++;
}
}
}
if(i==a/10000 && j!=a/100%100){
for(int k=1;k<=t[j];k++){
if(j>=a/100%100 && hui(i*10000+j*100+k)==1) sum++;
}
}
if(i==b/10000 && j!=b/100%100){
for(int k=1;k<=t[j];k++){
if(j<=b/100%100 && hui(i*10000+j*100+k)==1) sum++;
}
}
if(i!=a/10000 && i!=b/10000){
if(j==2 && f(i)==1){
for(int k=1;k<=29;k++){
if(hui(i*10000+j*100+k)==1) sum++;
}
}
else{
for(int k=1;k<=t[j];k++){
if(hui(i*10000+j*100+k)==1) sum++;
}
}
}
}
}
if(a<=92200229 && b>=92200229) sum++;
cout<<sum;
return 0;
}
输入一串字符,字符个数不超过100,且以“.”结束(. 后面没有其他字符)。 判断它们是否构成回文,如果是输出yes,否则输出no,并且输出字符的个数。
【输入】
ABBA.
【输出】
4
yes
【分析】所谓回文指从左到右和从右到左读一串字符的值是一样的,如12321,ABCBA,AA等。先读入要判断的一串字符(放入数组letter中),并记住这串字符的长度,然后首尾字符比较,并不断向中间靠拢,就可以判断出是否为回文。
#include<bits/stdc++.h>
using namespace std;
int main(){
char ch,letter[101];
cin>>ch;
int i=0,j=1;
while(ch!='.'){
i++;
letter[i]=ch;
cin>>ch;
}
cout<<i<<endl;
while((j<i)&&(letter[j]==letter[i])){
i--;
j++;
}
if(j>=i)cout<<"yes"<<endl;
else cout<<"no"<<endl;
return 0;
}
输入一个包含N 个正整数的数组,求出这个数组中包含的最长的回文数组是什么, 如果有相同长度的最长回文数,输出最靠前的一个。
输入格式
第一行1 个正整数:N,N的范围在[1,1000]。
第二行 N 个不同的正整数:范围在[1,10000]。
输出格式
多个正整数, 表示数组中最长的回文数组。
输入/输出例子1
输入:
9
2 6 1 9 7 9 1 5 3
输出
1 9 7 9 1
#include<bits/stdc++.h>
using namespace std;
bool f(int a[],int i,int j) {
for(;i<j;i++,j--){
if(a[i]!=a[j]){
return false;
}
}
return true;
}
int main(){
int n;
cin>>n;
int a[n+1];
for(int i=1;i<=n;i++){
cin>>a[i];
}
int x,y,max=-1;
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++) {
if(f(a,i,j)&&(j-i+1)>max){
x=i;
y=j;
max=j-i+1;
}
}
}
for(int i=x;i<=y;i++){
cout<<a[i]<<" ";
}
return 0;
}