Jackiesteed

www.github.com/jackiesteed

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

题目链接: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;
}
^^
posted on 2011-04-14 12:37  Jackiesteed  阅读(312)  评论(0编辑  收藏  举报