zoukankan      html  css  js  c++  java
  • Codeforces 792C. Divide by Three 贪心+分类讨论

    题意:给一个数字字符串,让你删除尽可能少的数位,使得这个数能够被3整除,并且不能有前导0存在。

    思路:所有数位加起来%3得到的值mod,那么就有三种情况

    mod==0:直接输出

    mod==1:要么删除一个数位%3=1的数,要么删除两个数位%3=2的数

    mod==2:要么删除一个数位%3=2的数,要么删除两个数位%3=1的数

    其中前导零有个大坑,如果我们删数位的两种情况都可以,但是有一种情况会导致删除前导零,删除前导零的位数也要计算进去,细节很重要。为了尽可能的少产生前导零,当我们删除数位的时候,应该从后往前删除。(这个过程我用了栈来存储,分别算了两种情况的删除位数 然后作比较)

    丑陋的AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e9+7;
    char num[100100];
    int deal_1[100100];
    bool vis_1[100100];
    int deal_2[100100];
    bool vis_2[100100];
    stack<int> sta1,sta2;   //sta1存放%3值为1的数位置的下标 sta2同理
    int len;
    int del_cnt1,del_cnt2;
    bool flag;
    void print(int n)
    {
        if(n==1)
        {
            if(del_cnt1==len)
            {
                if(flag)
                {
                    printf("0
    ");
                }
                else
                    printf("-1
    ");
                return;
            }
            for(int i=0; i<len; i++)
                if(vis_1[i])
                    printf(("%c"),num[i]);
        }
        else
        {
            if(del_cnt2==len)
            {
                if(flag)
                {
                    printf("0
    ");
                }
                else
                    printf("-1
    ");
                return;
            }
            for(int i=0; i<len; i++)
                if(vis_2[i])
                    printf(("%c"),num[i]);
        }
        printf("
    ");
    }
    
    void del(int n)     //计算前导0
    {
        int cnt=0;
        if(n==1)
        {
            for(int i=0; i<len; i++)
                if(vis_1[i])
                {
                    if(num[i]!='0')
                        return;
                    else if(del_cnt1)
                    {
                        vis_1[i]=false;
                        ++del_cnt1;
                    }
                }
        }
        else if(n==2)
        {
            for(int i=0; i<len; i++)
                if(vis_2[i])
                {
                    if(num[i]!='0')
                        return;
                    else if(del_cnt2)
                    {
                        vis_2[i]=false;
                        ++del_cnt2;
                    }
                }
        }
    }
    int main()
    {
        memset(vis_1,true,sizeof(vis_1));
        memset(vis_2,true,sizeof(vis_2));
        del_cnt1 = del_cnt2 = maxn;
        flag = false;
        len = strlen(num);
        int mod =0;
        for(int i=0; i<len; i++)
        {
            if(!flag && num[i]=='0')
                flag=true;
            deal_2[i] = deal_1[i] = (num[i]-'0')%3;
            mod += deal_1[i];
            if(deal_1[i]==1)
                sta1.push(i);
            else if(deal_2[i]==2)
                sta2.push(i);
        }
        mod%=3;
        if(mod == 0)
        {
            printf("%s
    ",num);
            return 0;
        }
        else if(mod == 1)
        {
            if(!sta1.empty())
            {
                del_cnt1=0;
                vis_1[sta1.top()] = false;
                ++del_cnt1;
                del(1);
            }
            if(sta2.size()>=2)
            {
                del_cnt2=0;
                vis_2[sta2.top()] = false;
                sta2.pop();
                vis_2[sta2.top()] = false;
                sta2.pop();
                del_cnt2+=2;
                del(2);
            }
        }
        else
        {
            if(!sta2.empty())
            {
                del_cnt1=0;
                vis_1[sta2.top()] = false;
                ++del_cnt1;
                del(1);
            }
            if(sta1.size()>=2)
            {
                del_cnt2=0;
                vis_2[sta1.top()] = false;
                sta1.pop();
                vis_2[sta1.top()] = false;
                sta1.pop();
                del_cnt2+=2;
                del(2);
            }
        }
    
        if(del_cnt1>del_cnt2)
            print(2);
        else
            print(1);
        return 0;
    }
  • 相关阅读:
    MongoDB 备份方法
    Wix制作安装包
    OWIN and Katana
    JavaScript的语法要点 4
    JavaScript的语法要点 3
    Docker配置镜像源(windows)
    Centos 7 安装gdal
    centos下forever安装nodejs服务
    Ngix初识
    arcgis支持mongodb
  • 原文地址:https://www.cnblogs.com/MyCodeLife-/p/7736391.html
Copyright © 2011-2022 走看看