zoukankan      html  css  js  c++  java
  • 【codeforces 792C】Divide by Three

    【题目链接】:http://codeforces.com/contest/792/problem/C

    【题意】

    让你删掉最少的数字使得剩下的数字%3==0

    【题解】

    看代码。。内置题解了现在。

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define ps push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%lld",&x)
    #define ref(x) scanf("%lf",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int N = 1e5+100;
    
    char s[N];
    int a[N],sum=0,len;
    bool bo[N];
    
    void out(){
        rep1(i,1,len)
            if (bo[i])
                cout << a[i];
        exit(0);
    }
    
    int main(){
        //freopen("F:\rush.txt","r",stdin);
        memset(bo,true,sizeof bo);
        scanf("%s",s+1);
        len = strlen(s+1);
        rep1(i,1,len) {
            a[i] = s[i]-'0';
            sum=(sum+a[i])%3;
        }
        if (sum==0) out();//直接就符合题意了
        if (len==1) return puts("-1"),0;//接下来要删除1个数字了 所以如果刚好一个数字是不合法的
        rep1(i,2,len)//从第二个数字开始删就不会存在不合法的了
            if (a[i]%3==sum)
                bo[i] = false,out();
        if (a[1]%3==sum && (a[2]!=0||(a[2]==0&&len==2))) bo[1] = false,out();
        //第一个数字的话要求第二个数字不是0
        //或者长度为2,那么也只要删除一个数字;
    
        if (len<=2) return puts("-1"),0;
        //接下来要至少删除两个数字了,所以小于等于2个数字都不合法了,从后往前删
        //这样能保证先删除的两个数字它们是靠后的;
        //如果有删除第一个和前缀的0更优的话,a[1]%3==sum,不可能是删掉的两个数字之一,所以不会有删除多余的0
        //所以直接删两个和为sum肯定更优(或者不会差).
        //最后再考虑a[1]%3==sum和有前缀0的情况
        int d =0;//判断有没有两个可以删的了;
        rep2(i,len,1)
            if ((a[i]%3)==(3-sum)){//这是两个合起来删掉能变成%3为0的情况
                if (d){
                    bo[i]=bo[d] = false;//删掉这两个数字
                    int fir=0;//有没有找到第一个非0数字;
                    rep1(j,1,len)
                        if (j!=i&&j!=d){
                            if (a[j]){
                                fir = 1;
                                break;
                            }
                            else//前面还没找到非0数字呢;
                                bo[j] = false;//是前缀0要删掉
                        }
                    if (fir){//找到了前缀非0
                        out();
                    }
                    else{//没找到
                        //已经确定大于两个数字了
                        return puts("0"),0;
                    }
                }
                else{
                    d = i;
                }
            }
        //最后在再考虑删掉第一个数虽然可以但要删除前缀0的情况;
        if (a[1]%3==sum){
            bo[1] = false;
            int j =1;
            while (j+1<=len-1 && a[j+1]==0) j++,bo[j] = false;//要留一个0
            out();
        }
        puts("-1");
        //printf("
    %.2lf sec 
    ", (double)clock() / CLOCKS_PER_SEC);
        return 0;
    }
    
  • 相关阅读:
    KMP算法的Next数组详解(转)
    公开封尘已久的即时通讯源码(转)
    《C语言编写 学生成绩管理系统》
    随想录(从编程语言到库、框架、软件)
    Effective Objective-C 2.0 笔记三(Literal Syntax简写语法)
    Java Swing 探索(一)LayoutManager
    Codeforces Round #FF 446 C. DZY Loves Fibonacci Numbers
    ARM体系结构与编程
    div:给div加滚动栏 div的滚动栏设置
    DS18B20
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626475.html
Copyright © 2011-2022 走看看