题目链接: 传送门

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,运用一点数学思想可以省略很多特判= =还是要注重多思考啊。

CF 214B Hometask(想法题)的更多相关文章

  1. HDU 4972 Bisharp and Charizard 想法题

    Bisharp and Charizard Time Limit: 1 Sec  Memory Limit: 256 MB Description Dragon is watching NBA. He ...

  2. CodeForces 111B - Petya and Divisors 统计..想法题

    找每个数的约数(暴力就够了...1~x^0.5)....看这约数的倍数最后是哪个数...若距离大于了y..统计++...然后将这个约数的最后倍数赋值为当前位置...好叼的想法题.... Program ...

  3. HDU - 5806 NanoApe Loves Sequence Ⅱ 想法题

    http://acm.hdu.edu.cn/showproblem.php?pid=5806 题意:给你一个n元素序列,求第k大的数大于等于m的子序列的个数. 题解:题目要求很奇怪,很多头绪但写不出, ...

  4. CF 701B Cells Not Under Attack(想法题)

    题目链接: 传送门 Cells Not Under Attack time limit per test:2 second     memory limit per test:256 megabyte ...

  5. CF 405C Unusual Product(想法题)

    题目链接: 传送门 Domino Effect time limit per test:1 second     memory limit per test:256 megabytes Descrip ...

  6. CF 405B Domino Effect(想法题)

    题目链接: 传送门 Domino Effect time limit per test:1 second     memory limit per test:256 megabytes Descrip ...

  7. HDU - 5969 最大的位或 想法题

    http://acm.hdu.edu.cn/showproblem.php?pid=5969 (合肥)区域赛签到题...orz 题意:给你l,r,求x|y的max,x,y满足l<=x<=y ...

  8. Codeforces Round #354 (Div. 2)-C. Vasya and String,区间dp问题,好几次cf都有这种题,看来的好好学学;

    C. Vasya and String time limit per test 1 second memory limit per test 256 megabytes input standard ...

  9. cf Canada cup A题

    A. Jumping Ball time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

随机推荐

  1. 前端手札--meta标记篇

    通用类: 声明编码 <meta charset='utf-8' /> SEO页面关键词 <meta name="keywords" content="y ...

  2. PHP 基础笔记

    数据类型 字符串 整数 浮点数 布尔值 数组 对象 NULL 未定义的变量,数据类型为 NULL. PHP 中数组和对象是不同的类型,而 js 中数组即为对象.(ps: es6 已经内置了 class ...

  3. 读懂IL代码就这么简单(二)

    一 前言 IL系列 第一篇写完后 得到高人指点,及时更正了文章中的错误,也使得我写这篇文章时更加谨慎,自己在了解相关知识点时,也更为细致.个人觉得既然做为文章写出来,就一定要保证比较高的质量,和正确率 ...

  4. Castle 多继承选择

    Castle 多继承选择 很多时候,我们定义了一个接口,但是这个接口会有多种不同的,这时IOC构造函数注入的时候,就需要自动选择对应的实现. public interface ITestService ...

  5. 学习Google Protocol buffer之语法

    上一篇结尾的时候问了几个问题,其实主要就是这个protoBuffer协议的语法,弄清楚语法后边才好开展工作嘛,不然大眼而对小眼儿,互相不认识,就没法玩耍了.其实就是学习怎么用google提供的这套 p ...

  6. WinForm 程序加管理员权限

    在Vista 和 Windows 7 及更新版本的操作系统,增加了 UAC(用户账户控制) 的安全机制,如果 UAC 被打开,用户即使以管理员权限登录,其应用程序默认情况下也无法对系统目录.系统注册表 ...

  7. XMl各种格式转换功能代码

    package com.cdv.test; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.File ...

  8. python学习笔记整理——列表

    Python 文档学习笔记 数据结构--列表 列表的方法 添加 list.append(x) 添加元素 添加一个元素到列表的末尾:相当于a[len(a):] = [x] list.extend(L) ...

  9. 工作框架各种使用整理---使用Cache

    <service verb="get" noun="Products"> <implements service="sang.pro ...

  10. Code.R团队展示

    团队成员: 031302620马凛凛(队长) 031302619吕昆明 031302319汪毓顺 031302404陈俊达 团队名称: Code.R 团队项目: 基于web的教师报课系统 团队成员风采 ...