• 2016中国大学生程序设计竞赛(长春) Ugly Problem 模拟+大数减法


    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5920

    我们的思路是:

    1. 对于一个串s,先根据s串前一半复制到后一半构成一个回文串,
    2. 如果这个回文串比s小,则做减法并递归;
    3. 如果相等直接结束;
    4. 如果大,那么找前一半离中心最近的一个非零数减1,并把这位之后到中心的数全都变为9,例如11000->11011,大了,所以变成10901;

    ps:因为大数相减要传指针参数,调了蛮久,发现指针的乱指了,所以开了一个二维数组,每一次算出的原串和回文串都用新的指针,也就是s[tot],ss[tot],temp[tot];

    /**************************************************************
        Problem:
        User: youmi
        Language: C++
        Result: Accepted
        Time:
        Memory:
    ****************************************************************/
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#include<bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <set>
    #include <sstream>
    #include <cmath>
    #include <queue>
    #include <deque>
    #include <string>
    #include <vector>
    #define zeros(a) memset(a,0,sizeof(a))
    #define ones(a) memset(a,-1,sizeof(a))
    #define sc(a) scanf("%d",&a)
    #define sc2(a,b) scanf("%d%d",&a,&b)
    #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define scs(a) scanf("%s",a)
    #define sclld(a) scanf("%I64d",&a)
    #define pt(a) printf("%d
    ",a)
    #define ptlld(a) printf("%I64d
    ",a)
    #define rep(i,from,to) for(int i=from;i<=to;i++)
    #define irep(i,to,from) for(int i=to;i>=from;i--)
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define lson (step<<1)
    #define rson (lson+1)
    #define eps 1e-6
    #define oo 0x3fffffff
    #define TEST cout<<"*************************"<<endl
    const double pi=4*atan(1.0);
    
    using namespace std;
    typedef long long ll;
    template <class T> inline void read(T &n)
    {
        char c; int flag = 1;
        for (c = getchar(); !(c >= '0' && c <= '9' || c == '-'); c = getchar()); if (c == '-') flag = -1, n = 0; else n = c - '0';
        for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0'; n *= flag;
    }
    ll Pow(ll base, ll n, ll mo)
    {
        ll res=1;
        while(n)
        {
            if(n&1)
                res=res*base%mo;
            n>>=1;
            base=base*base%mo;
        }
        return res;
    }
    //***************************
    
    int n;
    const int maxn=1000+10;
    const ll mod=1000000007;
    char ans[100][maxn];
    int tot=0;
    
    int Minus(char *source1, char *source2, char *result)//返回:1(s1>s2),-1(s1<s2),0(s1=s2)
    {
        int length1 = strlen(source1); // 被减数的长度
        int length2 = strlen(source2); // 减数的长度
        int i, j, k = 0;
        int temp; // 临时存放位相减的结果
        int bit = 0; // 借位,1表示需要借位,0表示不需要借位
        char ch; // 用于交换
        for (i = length1 - 1, j = length2 - 1; i >= 0 && j >= 0; --i, --j)
        {
            // 计算两个位之间的差值,同时要考虑借位
            temp = (source1[i] - '0') - (source2[j] - '0') - bit;
    
            if (temp < 0) // 需要借位
            {
                bit = 1;
                result[k++] = temp + 10 + '0';
            }
            else// 不需要借位
            {
                bit = 0;
                result[k++] = temp + '0';
            }
        }
    
        while (i >= 0) // length1 > length2的情况,结果为正数,将剩余数据赋值给计算结果数组
        {
            temp = source1[i--] - '0' - bit;
            if (temp < 0) // 需要借位
            {
                bit = 1;
                result[k++] = temp + 10 + '0';
            }
            else
            {
                bit = 0;
                result[k++] = temp + '0';
            }
        }
        while (j >= 0)// length1 < length2的情况,结果为负数,将剩余数据赋值给计算结果数组
        {
            temp = 10 - bit - (source2[j--] - '0');
            result[k++] = temp + '0';
        }
    
        // 对仍有进位的情况考虑,主要分两种:一种是strlen(p1)<strlen(p2),另一种是p1-p2<0,这两种情况bit为1
        if (bit == 1)
        {
            // 最低位肯定不会被借位,所以不需要减去借位
            // 只会向高位借位
            result[0] = 10 - (result[0] - '0') + '0';
            for (i = 1; i < k; i++)
            {
                result[i] = 10 - (result[i] - '0') - bit + '0';
            }
        }
    
        for (i = k - 1, j = 0; i >= j; --i, ++j)
        {
            ch = result[i];
            result[i] = result[j];
            result[j] = ch;
        }
        result[k] = '';
        while(result[0]=='0'&&strlen(result)>1)//去掉前导零
            strcpy(result,result+1);
        if(length1<length2)
            return -1;
        else if(length1>length2)
            return 1;
        else
        {
            for(int i=0;i<length1;i++)
            {
                if(source1[i]>source2[i])
                    return 1;
                else if (source1[i]<source2[i])
                    return -1;
            }
        }
        return 0;
    }
    char ss[100][maxn],temp[100][maxn];
    char s[100][maxn];
    void dfs()
    {
        int len=strlen(s[tot]);
        if(len==1)
        {
            strcpy(ans[tot],s[tot]);
            tot++;
            return;
        }
        int half=len/2;
        int pre=-1;
        int num=1-len%2;
        if(len%2==0)
        {
            for(int i=0;i<half;i++)
            {
                if(s[tot][i]!='0')
                    pre=max(pre,i);
                ss[tot][i]=s[tot][i];
            }
            for(int i=half;i<len;i++)
                ss[tot][i]=ss[tot][2*half-i-1];
        }
        else
        {
            for(int i=0;i<=half;i++)
            {
                if(s[tot][i]!='0')
                    pre=max(pre,i);
                ss[tot][i]=s[tot][i];
            }
            for(int i=half+1;i<len;i++)
                ss[tot][i]=ss[tot][2*half-i];
        }
        ss[tot][len]='';
        s[tot][len]='';
        int flag=Minus(s[tot],ss[tot],temp[tot]);
        if(flag==-1)
        {
            if(s[tot][pre]=='1'&&pre==0)
            {
                for(int i=0;i<len-1;i++)
                    ss[tot][i]='9';
                ss[tot][len-1]='';
            }
            else
            {
                ss[tot][pre]=s[tot][pre]-1;
                ss[tot][2*half-pre-num]=s[tot][pre]-1;
                for(int i=pre+1;i<2*half-pre-num;i++)
                    ss[tot][i]='9';
            }
            Minus(s[tot],ss[tot],temp[tot]);
            strcpy(ans[tot],ss[tot]);
            strcpy(s[tot+1],temp[tot]);
            tot++;
            dfs();
        }
        else if(flag==0)
        {
            strcpy(ans[tot],ss[tot]);
            tot++;
            return;
        }
        else
        {
            strcpy(ans[tot],ss[tot]);
            strcpy(s[tot+1],temp[tot]);
            tot++;
            dfs();
        }
    }
    int main()
    {
        int kase=0;
        sc(n);
        while(n--)
        {
            printf("Case #%d:
    ",++kase);
            tot=0;
            scs(s[tot]);
            while(s[tot][0]=='0'&&strlen(s[tot])>1)//去掉前导零
                strcpy(s[tot],s[tot]+1);
            dfs();
            pt(tot);
            rep(i,0,tot-1)
            puts(ans[i]);
        }
        return 0;
    }
    不为失败找借口,只为成功找方法
  • 相关阅读:
    吴裕雄天生自然SPRINGBOOT开发实战SpringBoot H2数据库
    吴裕雄天生自然SPRINGBOOT开发实战SpringBoot H2增删改查
    吴裕雄天生自然SPRINGBOOT开发实战处理 Error: Port should be >= 0 and < 65536. Received
    吴裕雄天生自然SPRINGBOOT开发实战处理Cannot load driver class: com.mysql.cj.jdbc.Driver
    吴裕雄天生自然SPRINGBOOT开发实战处理The import javax.persistence cannot be resolved
    吴裕雄天生自然SPRINGBOOT开发实战连接MYSQL数据库
    吴裕雄天生自然SPRINGBOOT开发实战处理annotation.GetMapping cannot be resolved
    算法笔记_day1_循环设计
    C++笔记 day004基础知识回顾
    算法笔记_day1_自顶向下(循环)
  • 原文地址:https://www.cnblogs.com/youmi/p/5931249.html
Copyright © 2020-2023  润新知