资源限制

时间限制: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。

把握住回文的定义:

只要第一个字等于最后一个字、第二个字等于倒数第二个字、第三个字等于倒数第三个字即可。

(这句话其实还可以简化,只要对称位置的字的相等即可)

其实根本无需纠结回文由几种字(数字或字母)组成。

posted on 2020-09-28 16:16  海月CSDN  阅读(98)  评论(0编辑  收藏  举报