zoukankan      html  css  js  c++  java
  • Codeforces 988E(贪心+模拟)

    传送门

    题面:

    E. Divisibility by 25
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You are given an integer nn from 11 to 10181018 without leading zeroes.

    In one move you can swap any two adjacent digits in the given number in such a way that the resulting number will not contain leading zeroes. In other words, after each move the number you have cannot contain any leading zeroes.

    What is the minimum number of moves you have to make to obtain a number that is divisible by 2525? Print -1 if it is impossible to obtain a number that is divisible by 2525.

    Input

    The first line contains an integer nn (1n10181≤n≤1018). It is guaranteed that the first (left) digit of the number nn is not a zero.

    Output

    If it is impossible to obtain a number that is divisible by 2525, print -1. Otherwise print the minimum number of moves required to obtain such number.

    Note that you can swap only adjacent digits in the given number.

    Examples
    input
    Copy
    5071
    
    output
    Copy
    4
    
    input
    Copy
    705
    
    output
    Copy
    1
    
    input
    Copy
    1241367
    
    output
    Copy
    -1
    
    Note

    In the first example one of the possible sequences of moves is 5071  5701  7501  7510  7150.


    题面描述:

        给你一个1到1e18的数,每次你可以将相邻的两个数交换,问你是否能在若干次交换后,使新的数能被25整除。如果能则输出最小的交换次数,否则输出-1。

    题目分析:

        我们需要发现,25的倍数有一个特性,无论其他数如何变,只要是以00、25、50、75结尾的数,必定是25的倍数。(因为对于这些数,无论前缀为多少,在除以5之后,最后的结尾总是能够为0或5,使得其结果还能被5整除)

        发现了这个规律之后,我们只需要贪心的进行比较,将原有的数贪心地分别以上述四个后缀为结尾,判断是否能够通过交换构成,如果能则贪心的选取最小的即可。

        而这个题还需要注意的一点前导0的处理,对于前导0的处理,因为每次的交换是相邻的交换的,因此第i位换到第j位只需要移动i-j次。所以如果出现构成00/25/50/75后缀后,出现前导0,我们只需要从第1位到第n-2位不断的寻找第一个非零的数,将此时的下标-1再加进cnt次数中进而跟答案比较即可。

    代码:

        

    #include <bits/stdc++.h>
    using namespace std;
    const int INF=0x3f3f3f3f;
    string str1,str2;
    bool vis=0;
    void Get(char a,char b,int n,int &ans){
        str2=str1;
        int cnt=0;
        int tmp=0;
        for(int i=n-1;i>=0;i--){//将最后一位置为字符b
            if(str2[i]==b){
                cnt++;
                for(int j=i;j<n-1;j++){
                    swap(str2[j],str2[j+1]);
                    tmp++;
                }
                break;
            }
        }
        for(int i=n-2;i>=0;i--){//将倒数第二位置为字符a
            if(str2[i]==a){
                cnt++;
                for(int j=i;j<n-2;j++){
                    swap(str2[j],str2[j+1]);
                    tmp++;
                }
                break;
            }
        }
        if(cnt==2){//如果能够构成后缀ab
            if(str2[0]!='0'){
                vis=1;
                //cout<<tmp<<endl;
                ans=min(ans,tmp);
            }//如果有前导0
            else{
                for(int i=0;i<n-2;i++){
                    if(str2[i]!='0'){//从第1位到n-2位找到第一个不为0的数
                        tmp+=i;
                        vis=1;
                        ans=min(ans,tmp);
                        break;
                    }
                }
            }
        }
    }
    int main()
    {
        cin>>str1;
        int len=str1.length();
        int ans=INF;
        //四种情况贪心取最小
        Get('0','0',len,ans);
        Get('2','5',len,ans);
        Get('5','0',len,ans);
        Get('7','5',len,ans);
        if(vis) cout<<ans<<endl;
        else puts("-1");
        return 0;
    }
    

  • 相关阅读:
    jQuery scroll事件
    jquery offset() 与position()方法的区别
    股票基本知识
    swfObject 使用说明
    javascript和swf在网页中交互的一些总结
    TCP 同步传输:客户端发送,服务器段接收
    读取Excel
    sql 执行顺序
    支付宝及时到帐接口
    Ajax中get提交和post提交的区别
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007278.html
Copyright © 2011-2022 走看看