牛客练习赛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; }