题目:回文数

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

Froggy 分别给出 10 个数码的出现次数,你需要找到一个由这些数码组成的最小的数,满足:

1. 这个数是回文的。

2. 不能有前导 0。

注:假设这个数字长度是 LLL,那么这个数是回文的当且仅当对于任意的 i∈[1,L]i\in [1,L]i∈[1,L],第 iii 位的数码和第 L−i+1L-i+1L−i+1 位的数码相同。

快来帮帮 Froggy 吧!

输入描述:

一行 10 个自然数,分别表示数码 0∼90\sim 90∼9 的出现次数。

输出描述:

 

如果无解,只输出 “-1”。(不含引号)

否则,输出一个数表示最小的解。

示例1

输入

0 2 4 2 0 2 0 0 0 0

输出

1223553221

示例2

输入

1 1 4 5 1 4 0 0 0 0

输出

-1

示例3

输入

4 0 2 3 0 0 0 2 0 0

输出

20037373002

示例4

输入

2 0 0 0 0 0 0 0 0 1

输出

-1

说明

注意不能有前导 0。

示例5

输入

1 0 0 0 0 0 0 0 0 0

输出

0

备注:

保证输入的所有数都不超过 100,且至少有一个数大于 0.

思路: 本人用的队列和栈模拟输出,将字符串分成两半,最先出现的不为零的数依次入队和入栈,输出符合先进先出,后进先出性质,然后再在输出答案之前做一些特判就OK了。

#include <iostream>
#include <stack>
#include <queue>
using namespace std;
int a[12];
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0),std::cout.tie(0);
    int h=0,k=0,j=-1;
    for(int i=0; i<10; i++)
    {
        int x;
        cin>>x;
        a[i]=x;
        if(x!=0&&x%2!=0)
        {
            h++;    //这里是判断奇数值的个数如果奇数值大于1肯定无法组成回文数
        }
        if(a[i]==0)  //这里是为了判断是否1-9全为零,全为零就无法组成
        {
            k++;
        }
        if(j==-1&&i!=0&&a[i]!=0&&a[i]>1)  //这是为了找到最先出现不等零且值大于一,因为要放到 
                                          //   开头最后一个位置也是这个数
                                          //   一定不要%2==0判断,我最初就掉到这个坑里
                                          //    因为奇数也有可能放在开头
            j=i;
    }
    if(h>1||k==10)                       //这里是一些特判
    {
        cout<<-1;
        return 0;
    }
    else
    {
        queue<int> q;
        stack<int> s;
        int t=-1;
        if(a[0]>1&&j==-1)
        {
            cout<<-1;
            return 0;
        }
        else if(a[0]==1&&j==-1)            //只有一个零也能组成
        {
            cout<<0;
            return 0;
        }
        q.push(j);                       //先将最先出现不为零的数入队,和入栈,这样即使有没
                                         //有零的存在都可以保证前导不为零
        s.push(j);
        a[j]-=2;
        if(t==-1&&a[j]==1)
            t=j;
        for(int i=0;i<10;i++)
        {
            while(a[i]!=0&&a[i]>1)
            {
                q.push(i);
                s.push(i);
                a[i]-=2;
            }
            if(t==-1&&a[i]==1)        //如果有基数就赋值给t
                t=i;
        }
        while(!q.empty())
        {
            cout<<q.front();
            q.pop();
        }
        if(t!=-1)                 //如果有基数就输出
            cout<<t;
        while(!s.empty())
        {
            cout<<s.top();
            s.pop();
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值