链接:登录—专业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;
}