zoukankan      html  css  js  c++  java
  • 分冶法解决大整数相乘 最近对问题

    1.大整数相乘

    问题描述:

     所以需要用字符串的方式进行存储,于是衍生了大整数相乘的问题

    两位数的示例:

    例如:11*11=(1*10^1+1*10^0)*(1*10^1+1*10^0)=1*10^2+(1+1)*10^1+1*10^0

    输入数据:11 11

    输出数据:121

    代码参考网址:https://www.bbsmax.com/A/VGzloP7ldb/

    //date:2020.5.9
    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 100;
    void reverse(char a[])
    {
        int len = strlen(a);
        for(int i = 0 ; i < len / 2; i++)
        {
            int temp = a[i];
            a[i] = a[len - i - 1];
            a[len - i -1] = temp;
        }
    }
    int main()
    {
        char a[maxn],b[maxn];
        int t[100] = {0};
        printf("Please enter 2 numbers: ");
        scanf("%s%s",a,b);
        reverse(a);
        reverse(b);
        if(strcmp(a,"0")==0||strcmp(b,"0")==0)
            cout<<"0"<<endl;
        else
        {
            int i,j;
            for(i = 0; i <strlen(b); i++)
            {
                int cnt = 0;
                for(j = 0; j < strlen(a); j++)
                {
                    int temp = (b[i] - '0') * (a[j] - '0');//表示结果
                    int tt= t[i+j] + temp + cnt;//表示与原来计算出对应级数相加
                    t[j+i] = tt % 10;
                    cnt = tt / 10;//cnt表示是否有进位
                }
                while(cnt != 0)
                {
                    t[j+i] = cnt % 10;
                    cnt = cnt / 10;
                    j++;//此处j++用于结果输出的时候i+j-2对应
                }
            }
            for(int k = i + j - 2; k >= 0; k--)//j比原来的位数多1
            {
                cout<<t[k];
            }
        }
        return 0;
    }

    代码的巧妙之处在于,i+j的结果就是10的几次的结果,所以十分巧妙,可以根据调试代码和阅读注释看懂代码,找了很久才找到这个好懂的代码

    2.分冶法解决最进对问题

    参照网址:https://www.cnblogs.com/zyxStar/p/4591897.html

     最简单的就是用蛮力法解决

    此处用的分冶法来解决(用的是递归,不断划分)

    先排序,然后不断平分,但是要比较两个区域相邻的最近对,所以问题变成求 左边 右边 相邻区域中间 这三个区域的最近对

     中间区域选的区间d大小 d=min(d1,d2)

    输入:

    1 1

    2 2

    3 3

    0

    输出:

    1.41

    //date:2020.5.9
    #include<bits/stdc++.h>
    using namespace std;
    const double inf = 1e20;
    const int maxn = 100005;
    
    struct Point
    {
        double x, y;
    } point[maxn];
    
    int n, mpt[maxn];
    
    //以x为基准排序
    bool cmpxy(const Point& a, const Point& b)
    {
        if (a.x != b.x)
            return a.x < b.x;
        return a.y < b.y;
    }
    
    bool cmpy(const int& a, const int& b)
    {
        return point[a].y < point[b].y;
    }
    
    double min(double a, double b)
    {
        return a < b ? a : b;
    }
    
    double dis(int i, int j)
    {
        return sqrt((point[i].x - point[j].x)*(point[i].x - point[j].x) + (point[i].y - point[j].y)*(point[i].y - point[j].y));
    }
    
    double Closest_Pair(int left, int right)
    {
        double d = inf;
        if (left == right)
            return d;
        if (left + 1 == right)
            return dis(left, right);
        int mid = (left + right) >> 1;
        double d1 = Closest_Pair(left, mid);
        double d2 = Closest_Pair(mid + 1, right);
        d = min(d1, d2);
        int i, j, k = 0;//左右两边的都已经找完了
        //分离出宽度为d的区间,找中间d最小的距离
        for (i = left; i <= right; i++)
        {
            if (fabs(point[mid].x - point[i].x) <= d)
                mpt[k++] = i;
        }
        sort(mpt, mpt + k, cmpy);
        //线性扫描
        for (i = 0; i < k; i++)
        {
            for (j = i + 1; j < k && point[mpt[j]].y - point[mpt[i]].y<d; j++)
            {
                double d3 = dis(mpt[i], mpt[j]);
                if (d > d3)
                    d = d3;
            }
        }
        return d;
    }
    
    int main()
    {
        while (~scanf("%d", &n) && n)
        {
            for (int i = 0; i < n; i++)
                scanf("%lf %lf", &point[i].x, &point[i].y);
            sort(point, point + n, cmpxy);
            printf("%.2lf
    ", Closest_Pair(0, n - 1) );
        }
        return 0;
    }

    核心就是划分再划分,直到最后划分的区域中只有一个或者两个点.这样,该区域的最近点对距离就是无穷大或者该两点的距离。这也是递归终止的条件。

    还有一个知识点是sort中最后一个参数的使用,值得思考

  • 相关阅读:
    网络知识: 物理层PHY 和 网络层MAC
    Android lowmemorykiller
    devres in linux driver
    spinlock in linux kernel
    JavaWeb图片URL中文乱码
    Linux 里的 2>&1含义
    python脚本linux上后台执行
    linux之定时任务
    python中if not x: 和 if x is not None: 和 if not x is None的使用和区别
    私钥和公钥的区别和联系
  • 原文地址:https://www.cnblogs.com/someonezero/p/12860222.html
Copyright © 2011-2022 走看看