牛客练习赛71——回文数(模拟+细节)
牛客练习赛71——回文数(模拟+细节)
真的细节。
思路:
记每一位的个数为num[i].根据题意可以得知:
无法构造的情况有:
1.有至少两个num[i]为奇数。
2.num[0]>=2并且其他数位只有一个并且只出现了一次,比如050,就无法避免前导0
注意特判最后一个样例。
正常做法分为两类,如果num[0]==0,说明无需考虑前导零的问题,直接从小到大枚举取一半构造出前半段,翻转得到后半段即可;否则,就要先把最小的非0位放在开始,然后再重复前面的步骤。如果num[i]%2的话,就将多出来的这个放在中间。
附上垃圾代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll>PLL;
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
#define I_int ll
inline ll read()
{
ll x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
char F[200];
inline void out(I_int x)
{
if (x == 0)
return (void) (putchar('0'));
I_int tmp = x > 0 ? x : -x;
if (x < 0)
putchar('-');
int cnt = 0;
while (tmp > 0)
{
F[cnt++] = tmp % 10 + '0';
tmp /= 10;
}
while (cnt > 0)
putchar(F[--cnt]);
//cout<<" ";
}
ll ksm(ll a,ll b,ll p)
{
ll res=1;
while(b)
{
if(b&1)
res=res*a%p;
a=a*a%p;
b>>=1;
}
return res;
}
const ll inf = 0x3f3f3f3f3f3f3f3f;
const int N=410,mod=1e8;
const double PI = 3.1415926535;
const double eps=1e-6;
const int maxn=1100;
int main()
{
int num[10];
int cnt=0,sum=0,pos;
for(int i=0; i<=9; i++)
{
num[i]=read();
if(num[i]&1)
cnt++,pos=i;
if(num[i]) sum++;
}
if(cnt>1||(num[0]>=2&&sum==2&&num[pos]==1))
puts("-1");
else if(sum==1&&num[0]==1) puts("0");
else
{
if(num[0]==0)
{
string s;
int flag=-1;
for(int i=0; i<=9; i++)
if(num[i])
{
for(int j=1; j<=num[i]/2; j++)
{
char t=i+'0';
s=s+t;
}
if(num[i]&1)
flag=i;
}
cout<<s;
if(flag!=-1)
cout<<flag;
reverse(s.begin(),s.end());
cout<<s<<endl;
}
else
{
string s;
int pos=1;
while(!num[pos]) pos++;
char ch=pos+'0';
s+=ch;
num[pos]-=2;
int flag=-1;
for(int i=0; i<=9; i++)
if(num[i])
{
for(int j=1; j<=num[i]/2; j++)
{
char t=i+'0';
s=s+t;
}
if(num[i]&1)
flag=i;
}
cout<<s;
if(flag!=-1)
cout<<flag;
reverse(s.begin(),s.end());
cout<<s<<endl;
}
}
return 0;
}