题目链接:https://www.spoj.pl/problems/DIV15/
蛋疼的题目,调了两个小时..
写出来主要是记录下需要注意的情况.
能被15整除,就是3和5的倍数,3的倍数的所有digit和仍是3的倍数,5的倍数末尾是0或5即可.
按程序结构描述,0,3,6,9,这几个digit都能添加进结果串中,因为他们都是3的倍数.
1,4,7,==1(mod 3),2,5,8==2(mod 3) m,所以可以把他们分成两组,分别用1和2来简单表示.
如果有0位,就不需要特殊来判5(目的都是找5的倍数).
如果都没有就是impossible.
有0时,写个循环,判断多少个1和多少个2能组成3的倍数,并是digit的总数最大,期间有特殊情况要处理,
就是x1+y1==x2+y2时,这里x1,y1表示使用x1个1,y1个2,x2,y2,同样,总数相等了,但是组合出来的string的
大小是不一样的,所以要加个判断.
对于没有0,而又5的情况,就是特意拿出一个5来,其他处理与上面答题相同.
附上代码:
View Code
^^
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
#include <climits>
using namespace std;
char str[1100];
int ones[3]={1,4,7};
int twos[3]={2,5,8};
int zeros[4]={0,3,6,9};
int cnt[10];
int res[10];
bool cmp(int n11,int n12,int n21,int n22,int flag)
{
if(flag)
{
cnt[5]--;
n12--;
n22--;
}
int tmp1[10]={0},tmp2[10]={0};
memset(tmp1,0,sizeof(tmp1));
memset(tmp2,0,sizeof(tmp2));
for(int i=2;i>=0;i--)
{
tmp1[ones[i]]+=min(cnt[ones[i]],n11);
n11-=min(cnt[ones[i]],n11);
tmp2[ones[i]]+=min(cnt[ones[i]],n21);
n21-=min(cnt[ones[i]],n21);
tmp1[twos[i]]+=min(cnt[twos[i]],n12);
n12-=min(cnt[twos[i]],n12);
tmp2[twos[i]]+=min(cnt[twos[i]],n22);
n22-=min(n22,cnt[twos[i]]);
}
if(flag)
{
cnt[5]++;
}
for(int i=9;i>=0;i--)
{
if(tmp1[i]!=tmp2[i])
return tmp1[i]<tmp2[i];
}
return false;
}
void work()
{
int len=strlen(str);
memset(cnt,0,sizeof(cnt));
memset(res,0,sizeof(res));
for(int i=0;i<len;i++)
{
cnt[str[i]-'0']++;
}
for(int i=0;i<4;i++)
{
res[zeros[i]]+=cnt[zeros[i]];
}
int r1s=0,r2s=0,n1s=0,n2s=0;
int tot=0;
for(int i=0;i<3;i++)
{
n1s+=cnt[ones[i]];
n2s+=cnt[twos[i]];
}
//printf("%d %d\n",n1s,n2s);
if(cnt[0])
{
for(int i=n1s;i>=0;i--)
{
for(int j=n2s;j>=0;j--)
{
if((i+2*j)%3==0)
{
if(tot<i+j)
{
tot=i+j;
r1s=i,r2s=j;
}
else if(tot==i+j)
{
if(cmp(r1s,r2s,i,j,0))
{
tot=i+j;
r1s=i,r2s=j;
}
}
break;
}
}
}
bool bingo=false;
for(int i=2;i>=0;i--)
{
res[ones[i]]+=min(r1s,cnt[ones[i]]);
r1s-=min(r1s,cnt[ones[i]]);
res[twos[i]]+=min(r2s,cnt[twos[i]]);
r2s-=min(r2s,cnt[twos[i]]);
}
for(int i=9;i>=1;i--)
{
if(res[i])
{
bingo=true;
break;
}
}
if(bingo)
{
for(int i=9;i>=0;i--)
{
for(int j=0;j<res[i];j++)
putchar(i+'0');
}
puts("");
}
else
{
puts("0");
}
}
else if(cnt[5])
{
for(int i=n1s;i>=0;i--)
{
for(int j=n2s;j>=1;j--)
{
if((i+2*j)%3==0)
{
if(tot<i+j)
{
tot=i+j;
r1s=i,r2s=j;
}
else if(tot==i+j)
{
if(cmp(r1s,r2s,i,j,1))
{
tot=i+j;
r1s=i,r2s=j;
}
}
break;
}
}
}
if(r2s)
{
r2s--;
cnt[5]--;
}
else
{
puts("impossible");
return;
}
bool bingo=false;
for(int i=2;i>=0;i--)
{
res[ones[i]]+=min(r1s,cnt[ones[i]]);
r1s-=min(r1s,cnt[ones[i]]);
res[twos[i]]+=min(r2s,cnt[twos[i]]);
r2s-=min(r2s,cnt[twos[i]]);
}
for(int i=9;i>=1;i--)
{
if(res[i])
{
bingo=true;
break;
}
}
if(bingo)
{
for(int i=9;i>=1;i--)
{
for(int j=0;j<res[i];j++)
putchar(i+'0');
}
puts("5");
}
else
{
puts("impossible");
return ;
}
}
else
puts("impossible");
}
int main()
{
//freopen("input.txt","r",stdin);
int T;
scanf("%d\n",&T);
while(T--)
{
gets(str);
work();
}
return 0;
}