资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
观察数字:12321,123321 都有一个共同的特征,无论从左到右读还是从右向左读,都是相同的。这样的数字叫做:回文数字。
本题要求你找到一些5位或6位的十进制数字。满足如下要求:
该数字的各个数位之和等于输入的整数。输入格式
一个正整数 n (10<n<100), 表示要求满足的数位和。
输出格式
若干行,每行包含一个满足要求的5位或6位整数。
数字按从小到大的顺序排列。
如果没有满足条件的,输出:-1样例输入
44
样例输出
99899
499994
589985
598895
679976
688886
697796
769967
778877
787787
796697
859958
868868
877778
886688
895598
949949
958859
967769
976679
985589
994499样例输入
60
样例输出
-1
OJ版
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int s[100];
int m=0;
int check(int a)
{
for(int i=0;i<100;i++)
{
if(s[i]==a)
return 1;
}
return 0;
}
void input(int temp)
{
if(check(temp)==0&&temp>10000)
{
s[m]=temp;
m++;
}
}
void output()
{
sort(s,s+100);
for(int i=0;i<100;i++)
{
if(s[i]!=0) cout<<s[i]<<endl;
}
}
int main()
{
int n;//给定数
cin>>n;
int temp;
for(int i=1;i<=9;i++)
{
for(int j=0;j<=9;j++)
{
for(int k=0;k<=9;k++)
{
if(i*4+j==n)
{
temp=i*10000+i*1000+j*100+i*10+i;
input(temp);
}
if(i*4+j*2==n)
{
temp=i*100000+i*10000+j*1000+j*100+i*10+i;
input(temp);
}
if(i*2+j*2+k*2==n)
{
temp=i*100000+j*10000+k*1000+k*100+j*10+i;
input(temp);
temp=i*100000+k*10000+j*1000+j*100+k*10+i;
input(temp);
}
if(i*2+j*2+k==n)
{
temp=i*10000+j*1000+k*100+j*10+i;
input(temp);
temp=j*10000+i*1000+k*100+i*10+j;
input(temp);
}
}
}
}
output();
if(s[100-m]==0)cout<<-1;
}
动态解释版
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int s[100];
int m=0;
int check(int a)
{
for(int i=0;i<100;i++)
{
if(s[i]==a)
return 1;
}
return 0;
}
void input(int temp,int i,int j,int k)
{
if(check(temp)==0&&temp>10000)
{
//cout<<i<<j<<k<<endl;
s[m]=temp;
//cout<<s[m]<<endl;
m++;
}
}
void output()
{
//cout<<m<<"!"<<endl;
sort(s,s+100);
for(int i=0;i<100;i++)
{
if(s[i]!=0) cout<<s[i]<<endl;
}
}
int main()
{
int n;//给定数
cin>>n;
int temp;
//三种组合形式
//9*4+8==44
//9*4+4*2=44
//9*2+8*2+5*2=44
for(int i=1;i<=9;i++)
{
for(int j=0;j<=9;j++)
{
for(int k=0;k<=9;k++)
{ //cout<<i<<j<<k<<endl;
if(i*4+j==n)
{
//cout<<"A"<<endl;
//cout<<i<<j<<k<<endl;
//cout<<i<<i<<i<<i<<j<<endl;
//temp=to_string(i*10000+i*1000+i*100+i*10+j);
temp=i*10000+i*1000+j*100+i*10+i;
input(temp,i,j,k);
}
if(i*4+j*2==n)
{
//cout<<"B"<<endl;
//cout<<i<<j<<k<<endl;
//cout<<i<<i<<i<<i<<j<<j<<endl;
//temp=to_string(i*100000+i*10000+i*1000+i*100+j*10+j);
temp=i*100000+i*10000+j*1000+j*100+i*10+i;
input(temp,i,j,k);
}
if(i*2+j*2+k*2==n)
{
//cout<<"C"<<endl;
//cout<<i<<j<<k<<endl;
//cout<<i<<i<<j<<j<<k<<k<<endl;
//temp=to_string(i*100000+i*10000+j*1000+j*100+k*10+k);
temp=i*100000+j*10000+k*1000+k*100+j*10+i;
input(temp,i,j,k);
temp=i*100000+k*10000+j*1000+j*100+k*10+i;
input(temp,i,j,k);
}
if(i*2+j*2+k==n)
{
//cout<<"D"<<endl;
//cout<<i<<j<<k<<endl;
//cout<<i<<i<<j<<j<<k<<k<<endl;
//temp=to_string(i*100000+i*10000+j*1000+j*100+k*10+k);
temp=i*10000+j*1000+k*100+j*10+i;
input(temp,i,j,k);
temp=j*10000+i*1000+k*100+i*10+j;
input(temp,i,j,k);
}
}
}
}
output();
//cout<<s[100-m];
if(s[100-m]==0)cout<<-1;
}
总结:
使用了穷举法。
分类讨论:有四种情况,分别为AABAA,AABBAA,ABCCBA,ABCBA(易漏)。
使用科学计数法将字符串转化为数字类型存储,便于排序和输出。
排序使用了sort函数,头文件是algorithm(算法)。
数组中的0也被排序了,排序之后,开头的很多元素均为0(默认从小到大排序)。
使用标记m可以获取第一个非0元素,以便判断数组是否为空。
还是写复杂了,有更加简单的方法...
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
bool flag=false;
for(int i=10000; i<1000000; i++)
{
int num[10];
int ans=0,t=0,s;
s=i;
while(s)
{
num[t++]=s%10;
ans+=s%10;
s/=10;
}
bool flag1=true;
for(int l=0,j=t-1; j>=0; l++,j--)
{
if(num[l]!=num[j])
{
flag1=false;
}
}
if(flag1&&ans==n)
{
cout<<i<<endl;
flag=true;
}
}
if(flag==false)
{
cout<<"-1"<<endl;
}
return 0;
}
写题之前,一定要思考一下,有没有更简单的方法
抓住问题的本质,给出一个定义,让电脑帮你判断。
比如这道题,其实不一定分为4种情况,也可以分成两种。
OOOOO,OOOOOO。
把握住回文的定义:
只要第一个字等于最后一个字、第二个字等于倒数第二个字、第三个字等于倒数第三个字即可。
(这句话其实还可以简化,只要对称位置的字的相等即可)
其实根本无需纠结回文由几种字(数字或字母)组成。