回文数(牛客)

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

输入

1 1 4 5 1 4 0 0 0 0

输出

-1

输入

4 0 2 3 0 0 0 2 0 0

输出

20037373002

输入

2 0 0 0 0 0 0 0 0 1

输出

-1

说明

注意不能有前导 0。

输入

1 0 0 0 0 0 0 0 0 0

输出

0

备注:

保证输入的所有数都不超过 101010,且至少有一个数大于 000。

分析:

1.如果有超过一个以上有奇数个数,说明不可能构成回文数。

2.如果零个数只有一个,其他数字没有,直接输出0。

3.前导零不行,并且满足字典序最小。

4.注意2 0 0 5 0 10 0 0 0 0这个例子。 


代码实现:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
ll a[10];
void solve()
{
   ll t=0;
   string s="";
    for(ll i=0;i<10;i++)
   {
       cin>>a[i];
       if(a[i]%2!=0)
       {
           t++;
       }
       if(t>1)//如果一个以上的数个数为奇数个,说明无法构成回文
       {
           cout<<"-1";
           return ;
       }
   }
    ll qd=-1,tm=0;
    for(ll i=1;i<10;i++)
    {
        if(a[i]>=2)//因为不能有前导0,所有要找0放哪
        {
            qd=i;
            break;
        }
        if(a[i]==0)
            tm++;
    }
    if(tm==8&&a[0]==0)
    {
        
    }
    else if(tm==9&&a[0]==1)
    {
        cout<<'0';
        return ;
    }
    else if(qd==-1)
    {
        cout<<"-1";
        return ;
    }
    ll res=0;
   for(ll i=1;i<10;i++)
   {
       ll j=a[i]/2;
       if(j>=1)
       {
               s=s+string(1,'0'+i);
           if(qd==i)//因为0最小的特殊性,只要不为前导0,则靠前输出
               s=s+string(a[0]/2,'0');
          
               s=s+string(j-1,'0'+i);
       }
      
       
   }
  string s1=s;
  for(ll i=0;i<10;i++)
  {
      if(a[i]%2!=0)
      {
          s=s+string(1,'0'+i);//最中间的特殊处理
          break;
      }
  }
reverse(s1.begin(),s1.end());//反转后接到一起
s=s+s1;
cout<<s;
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    ll t=1;
    while(t--)
    solve();
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值