• AtCoder Beginner Contest 182C


    C - To 3

    Time Limit: 2 sec / Memory Limit: 1024 MB

    Score : 300300 points

    Problem Statement

    Given is a positive integer N, where none of the digits is 0.
    Let k be the number of digits in N. We want to make a multiple of by erasing at least 0 and at most k−1 digits from N and concatenating the remaining digits without changing the order.
    Determine whether it is possible to make a multiple of 3 in this way. If it is possible, find the minimum number of digits that must be erased to make such a number.

    Constraints

    • 1N<10^18
    • None of the digits in N is 0.

    Input

    Input is given from Standard Input in the following format:

    N

    Output

    If it is impossible to make a multiple of 3, print -1; otherwise, print the minimum number of digits that must be erased to make such a number.


    Sample Input 1 

    35

    Sample Output 1 

    1

    By erasing the 5, we get the number 3, which is a multiple of 3. Here we erased the minimum possible number of digits  1.


    Sample Input 2 

    369

    Sample Output 2

    0

    Note that we can choose to erase no digit.


    Sample Input 3

    6227384

    Sample Output 3 

    1

    For example, by erasing the 8, we get the number 622734, which is a multiple of 3.


    Sample Input 4 

    11

    Sample Output 4

    -1

    Note that we must erase at least 0and at most k1digits, where k is the number of digits in N, so we cannot erase all the digits.
    In this case, it is impossible to make a multiple of 3 in the way described in the problem statement, so we should print -1.

    解题思路:题意是对N进行几次删除位数的操作能让删除后的位数为3的倍数,地球人都知道三的倍数有个特点,就是每一位相加之和是三的倍数

    再看看数据的大小n是1e18的,很小可以直接搜索(但似乎听说正解是动规?喵喵喵?)

    Code:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<string>
    
    int cnt=0;
    bool vis[30];
    
    bool check(std::string ch) {//判断的函数,如果该数的各个位数之和为3的倍数则返回true
        int sum = 0;
        int len = ch.length();
        for(int i = 0; i < ch.length(); ++i) {
            sum += ch[i] - '0';
        }
        if(sum % 3)
        return false;
        cnt = std::max(len,cnt);//保证删除的位数最小
        return true;
    }
    
    void dfs(std::string ch,int loc) {
        if(check(ch)) {//如果找到了就不搜索了
            return;
        }
        for(int i = 0; i < ch.length(); ++i) {
            if(!vis[i]) {
                std::string temp = ch;
                temp.erase(i,1);//删除第i个位置的元素
                vis[i] = true;
                dfs(temp,i+1);
                vis[i] = false;//回溯搜索法
            }
        }
    }
    
    int main()
    {
        int a,b;
        std::string ch;
        std::cin>>ch;
        dfs(ch,0);
        if(cnt == 0)//如果全都删了
        std::cout << -1 << "
    ";
        else
        std::cout << ch.length() - cnt << "
    ";
        return 0;
    }

     简单的搜索hhh

  • 相关阅读:
    可扩展多线程异步Socket服务器框架EMTASS 2.0
    认识迅雷界面引擎
    C语言 二维数组(指针)动态分配和释放(转)
    二维数组与双重指针(转)
    VC++6 调用teststand api的方法
    [VC6] 小谈如何解决VC6.0 open崩溃的问题(已解决)(转)
    Linux下C与Mysql的混合编程(转)
    VS2010生成安装包制作步骤 (转)
    SAO总结
    JS OOP编程
  • 原文地址:https://www.cnblogs.com/Mangata/p/13950678.html
Copyright © 2020-2023  润新知