HDU 3925 Substring 【大数相减】

题目意思是,给你提供两个数字 a 和 b

a 可以不断的往上加, 直到b 为其子串

问的是 a 最小加几?

显而易见,a  的数据范围给了10 ^100非常大,直接模拟肯定不行

那么就用 b 减去 a 来找,也算是一种模拟的方法

举个例子, a = 1299, b = 33

<1>33     330  3300   33000

(12)99   (1)299  1299    1299

------   -------- --------     -------

34      31  2001   32001

如果当前 b 比a的部分小,在前面添1

每次比较完在b后面添0

取所有比较结果中最小的数字作为答案

当然,如果a <= b 是可以直接得到答案的 ans = b - a

但是这题用G++提交不知道为什么会WA

C++就能过

Source code:

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#define LL long long
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
#define MOD 1000000007

using namespace std;

string Plus(string s1,string s2){
     if(s1.length() < s2.length()){
          string temp = s1;
          s1 = s2;
          s2 = temp;
     }
     for(int i = s1.length() - 1, j = s2.length() - 1; i >= 0; --i, --j){
          s1[i] = char(s1[i] + (j >= 0 ? s2[j]- ‘0‘ : 0));
          if(s1[i] - ‘0‘ >= 10){
              s1[i] = char((s1[i] - ‘0‘) % 10 + ‘0‘);
              if(i) ++s1[i-1];
              else  s1 += ‘1‘;
          }
     }
     return s1;
}

string Minus(string a,string b){
    string c="",ans="",t;
    int flag = 0, k = 0;
    bool flag2 = false;
    if(a.length() < b.length() || (a.length() == b.length()&& a.compare(b) < 0)){
        t = a;
        a = b;
        b = t;
        flag2 = true;
    }
    int i = a.length() - 1, j = b.length() - 1;
    while(i >= 0 && j >= 0){
        if(a[i] + flag > b[j]){
          c += a[i] + flag - b[j] + ‘0‘;
          flag = 0;
        }
        else if(a[i] + flag == b[j]){
          c += ‘0‘;
          flag = 0;
        }
        else{
          c += (a[i] - ‘0‘) + flag + 10 - (b[j] - ‘0‘) + ‘0‘;
          flag = -1;
        }
        --i;
        --j;
        ++k;
    }
    while(i >= 0){
        if(a[i] + flag < ‘0‘){
            c += a[i] + flag + 10 + ‘0‘;
            flag = -1;
        }
        else{
            c += a[i] + flag;
            flag = 0;
        }
        --i;
        ++k;
    }
    int len = k - 1;
    while(c[len] == ‘0‘ && len > 0) --len;
    for(j = 0; j <= len; ++j)
      ans += c[j];
    if(flag2){
        ans += ‘-‘;
    }
    char tt;
    for(i = 0, j = ans.length()-1; i < j; ++i, --j){
        tt = ans[i];
        ans[i] = ans[j];
        ans[j] = tt;
    }
    return ans;
}

bool judge(string a, string b){
    if(a.size() < b.size()) return false;
    else if(a.size() > b.size())    return true;
    else{
        for(int i = 0; i < a.size(); ++i){
            if(a[i] > b[i]) return true;
            else if(a[i] < b[i]) return false;
        }
    }
}

int main(){
    int i, j, t, n, m, numCase = 0;
    string s1,s2, hh;
    string cnt, ans;
    bool flag1;
    scanf("%d",&t);
    while(t--){
        cin >> s1 >> s2;
        flag1 = false;
        int len1 = s1.size();
        int len2 = s2.size();
        if(judge(s2, s1)){
            cout << "Case #" << ++numCase << ": " << Minus(s2, s1) << endl;
            continue;
        }
        for(i = 0; i < len1 - len2; ++i){
            string ww = s1.substr(i, len2);
            if(ww.compare(s2) == 0){
                flag1 = true;
                break;
            }
        }
        if(flag1){
            cout << "Case #" << ++numCase << ": " << ‘0‘ << endl;
            continue;
        }
        for(i = 0; i < len1 - len2 + 2; ++i){
            if(i == len1 - len2 + 1){
                hh = s1.substr(len1 - len2 - i + 1, i + len2 - 1);
            } else{
                hh = s1.substr(len1 - len2 - i, i + len2);
            }
            if(judge(hh, s2)){
                string gg = "1";
                gg += s2;
                ans = Minus(gg ,hh);
            }
            else{
                ans = Minus(s2 ,hh);
            }
            s2 += "0";
            if(i == 0){
                cnt = ans;
            } else{
                if(judge(cnt, ans)){
                    cnt = ans;
                }
            }
        }
        cout << "Case #" << ++numCase << ": " << cnt << endl;
    }

    return 0;
}
时间: 2024-08-26 07:50:47

HDU 3925 Substring 【大数相减】的相关文章

华为机试—大数相减

题目:大数相减 输入两行字符串正整数,第一行是被减数,第二行是减数,输出第一行减去第二行的结果. 备注:1.两个整数都是正整数,被减数大于减数 示例: 输入:1000000000000001       1 输出:1000000000000000 #include <stdio.h> #include <string.h> #define MAX 100 //100位大数相减 int bigNumSub(char a[],char b[],char sub[]) { int i=0

[算法]大数相减

今天在小米OJ上看到一道题(https://code.mi.com/problem/list/view?id=3), 很有意思, 试着做了一下 描述: 两个长度超出常规整形变量上限的大数相减,请避免使用各语言内置大数处理库,如 Java.math.BigInteger 等. 输入: 有 N 行测试数据,每一行有两个代表整数的字符串 a 和 b,长度超过百位.规定 a>=b,a, b > 0. 测试结果可以用 linux 小工具 bc进行测试是否正确. 输出: 返回表示结果整数的字符串. 输入样

每日一练:#002大数相减

描述 两个长度超出常规整形变量上限的大数相减,请避免使用各语言内置大数处理库,如 Java.math.BigInteger 等. 输入 有 N 行测试数据,每一行有两个代表整数的字符串 a 和 b,长度超过百位.规定 a>=b,a, b > 0. 测试结果可以用 linux 小工具 bc进行测试是否正确. 输出 返回表示结果整数的字符串. 输入样例 1231231237812739878951331231231237812739878951331231231237812739878951331

HDU 4652 Dice:期望dp(成环)【错位相减】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4652 题意: 给你一个有m个面的骰子. 两种询问: (1)"0 m n": "最后n次点数均相同"的投掷次数期望. (2)"1 m n": "最后n次点数各不相同"的投掷次数期望. 题解: 表示状态: dp[i] = expectation (当前已经有i个点数相同/不相同) 找出答案: ans = dp[0] 如何转移: 一.都

【算法】大数加减

超长的整型加减法可以用数组int来存储,每个单元可以存储1~9位数字,然后模拟手算过程 大数乘除法,稍复杂,(挖坑)续更.. ====================分割线==================== 1 /************************************************* 2 Copyright: CheerM 3 Author: CheerM 4 Date: 2016-11-02 5 Description: 实现超长int型的加减运算.输入任意长

常见的编程问题(一)少大数加减

存储区的概念 常见的存储区域可分为: 栈 由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等. 堆 由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete.如果程序员没有释放掉,程序会一直占用内存,导致内存泄漏,在程序结束后,操作系统会自动回收. 由malloc等分配的内存块,它和堆是十分相似的,不过它是用free来释放分配的内存. 全局/静态存储区 全局变量和静态变量被分配到同一块内存中,在

YT15-HDU-How many fibs(大数相加法)

Problem Description Recall the definition of the Fibonacci numbers: f1 := 1 f2 := 2 fn := fn-1 + fn-2 (n >= 3) Given two numbers a and b, calculate how many Fibonacci numbers are in the range [a, b]. Input The input contains several test cases. Each

C语言复习---获取最大公约数(辗转相除法和更相减损法)

源自:百度百科 辗转相除法 辗转相除法:辗转相除法是求两个自然数的最大公约数的一种方法,也叫欧几里德算法. 例如,求(319,377): ∵ 319÷377=0(余319) ∴(319,377)=(377,319): ∵ 377÷319=1(余58) ∴(377,319)=(319,58): ∵ 319÷58=5(余29) ∴ (319,58)=(58,29): ∵ 58÷29=2(余0) ∴ (58,29)= 29: ∴ (319,377)=29. 用辗转相除法求几个数的最大公约数,可以先求出

asp.net(C#)时间相减 得到天数、小时、分钟、秒差

asp.net(C#)时间相减 得到天数.小时.分钟.秒差 DateTime dtone = Convert.ToDateTime("2007-1-1 05:00:00"); DateTime dtwo = Convert.ToDateTime("2007-1-5 08:00:00"); TimeSpan span = dtone.Subtract(dtwo); //算法是dtone 减去 dtwo tss.Text = span.Days + "天&qu