您的位置:首页 > 其它

Codeforces Round #131 (Div. 2)214B Hometask(想法题)

2016-07-19 00:32 302 查看

题目链接: 传送门

Hometask

Time Limit: 2 seconds     Memory Limit: 256 megabytes

Description

Furik loves math lessons very much, so he doesn't attend them, unlike Rubik. But now Furik wants to get a good mark for math. For that Ms. Ivanova, his math teacher, gave him a new task. Furik solved the task immediately. Can you?
You are given a set of digits, your task is to find the maximum integer that you can make from these digits. The made number must be divisible by 2, 3, 5 without a residue. It is permitted to use not all digits from the set, it is forbidden to use leading zeroes.
Each digit is allowed to occur in the number the same number of times it occurs in the set.

Input

A single line contains a single integer n (1 ≤ n ≤ 100000) — the number of digits in the set. The second line contains n digits, the digits are separated by a single space.

Output

On a single line print the answer to the problem. If such number does not exist, then you should print -1.

Sample Input

1
0

11
3 4 5 4 5 3 5 3 4 4 0

8
3 2 5 1 5 2 2 3

Sample Output

0

5554443330

-1

思路:

题目大意:给一个都是数字的集合,组成一个尽量大的数使之能被2,3,5整除。
找出集合中是否有9,没有则停止判断。对于给出的数字集合,看总和是否能被3整除,能直接从大到小输出,不行的话,对3取模,对取模结果(1或2)单独判断,删除集合中某些数字是否能被3整除,不行则停止。输出是忽略前导0。(训练赛时在对模结果为1的特判中折腾了好久。模结果为1,则可以删去集合中一个对3取模也为1的数,或是删去两个对3取模为2的数,模结果为2同理。 官方题解

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef __int64 LL;
struct Node
{
LL cnt,val;
bool flag;
Node():cnt(0),val(0),flag(false) {}
};
bool cmp(Node x,Node y)
{
return x.val > y.val;
}

int main()
{
LL N,tmp,maxx = 0,sum = 0;
bool Isz = false;
Node num[15];
scanf("%I64d",&N);
for (int i = 0; i < N; i++)
{
scanf("%I64d",&tmp);
sum += tmp;
num[tmp].val = tmp;
num[tmp].cnt++;
num[tmp].flag = true;
if (tmp > maxx)
{
maxx = tmp;
}
if (tmp == 0)
{
Isz = true;
}
}
if (!Isz)
{
printf("-1\n");
}
else
{
if (sum % 3 == 0)
{
if (num[maxx].val == 0)
{
printf("0\n");
}
else
{
for (int i = maxx; i >= 0; i--)
{
if(num[i].flag)
{
while (num[i].cnt--)
{
printf("%I64d",num[i].val);
}
}
}
printf("\n");
}
}
else
{
LL r = sum % 3;
bool Can = false;
LL cnt = 0;
if (r == 1)
{
for (int i = 1; i <= maxx ; i+=3)
{
if (num[i].flag && num[i].cnt)
{
Can = true;
num[i].cnt--;
if (num[i].cnt == 0)
{
num[i].flag = false;
num[i].val = 0;
}
break;
}
}
if(!Can)
{
for (int i = 2;i <= maxx;i+=3)
{
if (num[i].flag && num[i].cnt)
{
while (num[i].cnt--)
{
cnt++;
if (num[i].cnt == 0)
{
num[i].flag = false;
}
if (cnt == 2 || num[i].cnt == 0)
{
if (cnt == 2)
{
Can = true;
}
break;
}
}
if (cnt == 2)
{
Can = true;
break;
}
}
}
}
}
else if (r == 2)
{
for (int i = 2; i <= maxx; i+=3)
{
if (num[i].flag && num[i].cnt)
{
Can = true;
num[i].cnt--;
if(num[i].cnt == 0)
{
num[i].flag = false;
num[i].val = 0;
}
break;
}
}
if (!Can)
{
for (int i = 1; i <= maxx; i+=3)
{
if (num[i].flag && num[i].cnt)
{
while (num[i].cnt--)
{
cnt++;
if (num[i].cnt == 0)
{
num[i].flag = false;
}
if (cnt == 2 || num[i].cnt == 0)
{
if (cnt == 2)
{
Can = true;
}
break;
}
}
}
if (cnt == 2)
{
Can = true;
break;
}
}
}
}
if (!Can)
{
printf("-1\n");
}
else
{
bool Noz = false;
for (int i = 0;i <= maxx;i++)
{
if (num[i].flag && num[i].val)
{
Noz = true;
break;
}
}

if (Noz)
{
for (int i = maxx;i >= 0;i--)
{
if (num[i].flag && num[i].cnt)
{
while (num[i].cnt--)
{
printf("%I64d",num[i].val);
}
}
}
printf("\n");
}
else
{
printf("0\n");
}
}
}
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int main()
{
int N;
while (~scanf("%d",&N))
{
int ans[10] = {0};
int tmp,sum = 0;
bool flag = false;
for (int i = 0;i < N;i++)
{
scanf("%d",&tmp);
ans[tmp]++;
sum += tmp;
}
if (ans[0] == 0)
{
printf("-1\n");
}
else
{
flag = true;
if (sum % 3 == 1)
{
if (ans[1] + ans[4] + ans[7])
{
for (int i = 1;i <= 7;i += 3)
{
if (ans[i])
{
ans[i]--;
break;
}
}
}
else if (ans[2] + ans[5] + ans[8] >= 2)
{
for (int i = 2,j = 1;i <= 8;i+=3)
{
while (ans[i] && j <= 2)
{
ans[i]--;
j++;
}
}
}
}
else if (sum % 3 == 2)
{
if (ans[2] + ans[5] + ans[8])
{
for (int i = 2;i <= 8;i += 3)
{
if (ans[i])
{
ans[i]--;
break;
}
}
}
else if (ans[1] + ans[4] + ans[7] >= 2)
{
for (int i = 1,j = 1;i <= 7;i += 3)
{
while (ans[i] && j <= 2)
{
ans[i]--;
j++;
}
}
}
}
}

if (flag)
{
if (ans[1] + ans[2] + ans[3] + ans[4] + ans[5] + ans[6] + ans[7] + ans[8] + ans[9])
{
for (int i = 9;i >= 0;i--)
{
while (ans[i]--)
{
printf("%d",i);
}
}
}
else
{
printf("0");
}
printf("\n");
}
}
return 0;
}

后来参考了别人代码= =果然自己太native,运用一点数学思想可以省略很多特判= =还是要注重多思考啊。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: