ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

2022春季 哈工大 硕士算法设计与分析 实验一分治算法

2022-06-07 08:32:09  阅读:162  来源: 互联网

标签:const temp nums second 算法 哈工大 2022 pair first


 

 

枚举凸包:

算法思想: 每四个点判断是否有其中一个点在另外三个点的包围内, 如果是, 则标记为内点,重复选取,直至没有内点
#include <iostream>
#include <cmath>
#include <cstring>
#include <vector>
#include <utility>
#include <ctime>
using namespace std;
int n;
vector<int> temp;
bool vis[1010];
// 求平行四边形面积,因为求三角形会有精度损失
double area(const pair<double, double>& a, const pair<double, double>& b,
           const pair<double, double>& c)
{
    double ret = fabs((b.first - a.first) * (c.second - a.second) - (c.first - a.first)* (b.second - a.second));
    return ret;
}
//如果d在三角形abc内部,则Sabc = Sabd + Sacd + Sbcd
void check(const pair<double, double>& a, const pair<double, double>& b,
           const pair<double, double>& c, const pair<double, double>& d,
           const int& id)
{
    double A = area(a, b, c), B = area(a, b, d), C = area(a, c, d), D = area(b, c, d);
    if(A == B + C + D && B != 0 && C != 0 && D != 0)
        vis[id] = 1;
}

// 对每四个点都进行判断,标记内部点
void Convex(vector<pair<double, double> >& nums, int k)
{
    if(temp.size() == 4)
    {

        check(nums[temp[0]], nums[temp[1]], nums[temp[2]], nums[temp[3]], temp[3]);
        check(nums[temp[0]], nums[temp[1]], nums[temp[3]], nums[temp[2]], temp[2]);
        check(nums[temp[0]], nums[temp[2]], nums[temp[3]], nums[temp[1]], temp[1]);
        check(nums[temp[1]], nums[temp[2]], nums[temp[3]], nums[temp[0]], temp[0]);
        return;
    }
    for(int i = k + 1; i < nums.size(); i++)
    {
        temp.push_back(i);
        Convex(nums, i);
        temp.pop_back();
    }
}



int main()
{
    int isborder[101][101];
    memset(isborder, 0, sizeof(isborder));
    vector<pair<double, double> > nums; //存储点
    memset(vis, 0, sizeof(vis));
    cin >> n;
    if(n < 3)
    {
        cout << "Points not enough" << endl;
        return 0;
    }
    for(int i = 0; i < n; i++)
    {
        double x, y;
        cin >> x >> y;
        isborder[(int)x][(int)y] = -1;

        nums.push_back(pair<double, double> (x, y));
    }
    clock_t startTime, endTime;
    startTime = clock();

    Convex(nums, -1);
    endTime = clock();

    cout << "result: " << endl;
    for(int i = 0; i < n; i++)
    {
        if(vis[i] == 0)
        {
            cout << nums[i].first << " " << nums[i].second << endl;
            isborder[(int)nums[i].first][(int)nums[i].second] = 1;

        }
    }
        for(int i = 0; i <= 100; i++)
    {
        for(int j = 0; j <= 100; j++)
        {
            if(isborder[i][j] == -1)
                cout << "6";
            else if(isborder[i][j] == 0)
                cout << "*";
            else
                cout << "7";
        }
        cout << endl;

    }
    cout << "The run time is: " <<(double)(endTime - startTime) << "ms" << endl;

    return 0;
}
View Code

graham凸包:

算法思想: 1、求y值最小的点p 2、以p为原点,将其他点按极角大小逆时针排序 3、将前三个点放入vector,遍历剩余点,如果vector[size - 2] vector[size - 1] points[i]不是逆时针方向, 则pop_back()
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <ctime>
using namespace std;
int n;

bool cmp1(const pair<double, double>& a, const pair<double, double>& b)
{
    return a.second < b.second;
}
//bool cmp2(const pair<double, double>& a, const pair<double, double>& b)
//{
//    double cita1 = atan(a.second / a.first);
//    cita1 = cita1 < 0 ? cita1 + 3.14 : cita1;
//    double cita2 = atan(b.second / b.first);
//    cita2 = cita2 < 0 ? cita2 + 3.14 : cita2;
//    if(cita1 == cita2)
//        return a.first < b.first;
//    else if(cita1 < cita2)
//        return 1;
//    else return 0;
//}

int cross(const pair<double, double> &a, const pair<double, double> &b, const pair<double, double> &c)
{
    return (b.first - a.first) * (c.second - a.second) - (c.first - a.first) * (b.second - a.second);
}

bool cmp2(const pair<double, double>& a, const pair<double, double>& b)
{
    pair<double, double> c;
    c.first = 0;
    c.second = 0;
    if(cross(c, a, b)==0)
        return a.first < b.first;
    else
        return cross(c, a, b) > 0;

}

vector<pair<double, double> > Graham(vector<pair<double, double> > &nums)
{
    // 求最小y的点point,用了个排序
    sort(nums.begin(), nums.end(), cmp1);
    double x = nums[0].first, y = nums[0].second;
    // 将所有的点移动到point为原点的坐标系下
    for(int i = 0; i < nums.size(); i++)
    {
        nums[i].first -= x;
        nums[i].second -= y;
    }
    // 按照极角排序
    sort(nums.begin() + 1, nums.end(), cmp2);


    vector<pair<double, double> > ret;
    ret.push_back(nums[0]);
    ret.push_back(nums[1]);
    ret.push_back(nums[2]);
    // 遍历剩余结点,如果当前结点不在上一个结点的逆时针方向,则移除上一个结点,直至符合
    for(int i = 3; i < nums.size(); i++)
    {
        while(ret.size() >= 2 && cross(ret[ret.size() - 2], ret[ret.size() - 1], nums[i]) <= 0)
            ret.pop_back();
        ret.push_back(nums[i]);
    }
    for(int i = 0; i < ret.size(); i++)
        ret[i].first += x, ret[i].second += y;
    return ret;
}


int main()
{
    int isborder[101][101];
    memset(isborder, 0, sizeof(isborder));
    vector<pair<double, double> > nums;
    cin >> n;
    if(n < 3)
    {
        cout << "Points not enough" << endl;
        return 0;
    }
    for(int i = 0; i < n; i++)
    {
        double x, y;
        cin >> x >> y;
        isborder[(int)x][(int)y] = -1;
        nums.push_back(pair<double, double> (x, y));
    }

    clock_t startTime, endTime;
    startTime = clock();

    vector<pair<double, double> > ret = Graham(nums);
    endTime = clock();
    cout << "result: " << endl;
    for(int i = 0; i < ret.size(); i++)
    {

        cout << ret[i].first << " " << ret[i].second << endl;
        isborder[(int)ret[i].first][(int)ret[i].second] = 1;

    }
    for(int i = 0; i <= 100; i++)
    {
        for(int j = 0; j <= 100; j++)
        {
            if(isborder[i][j] == -1)
                cout << "6";
            else if(isborder[i][j] == 0)
                cout << "*";
            else
                cout << "7";
        }
        cout << endl;

    }
    cout << "The run time is: " <<(double)(endTime - startTime) << "ms" << endl;



    return 0;
}
View Code

分治凸包:

算法思想: 1、求各点坐标x值的中点m 2、以x = m为分界线将点集合分为Ql和Qr两个子集和 3、递归在Ql和Qr中求凸包 4、将两个凸包按规则合并到一起 5、凸包算法使用graham算法
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <ctime>
using namespace std;
int n;

bool cmp1(const pair<double, double>& a, const pair<double, double>& b)
{
    return a.second < b.second;
}
//bool cmp2(const pair<double, double>& a, const pair<double, double>& b)
//{
//    double cita1 = atan(a.second / a.first);
//    cita1 = cita1 < 0 ? cita1 + 3.14 : cita1;
//    double cita2 = atan(b.second / b.first);
//    cita2 = cita2 < 0 ? cita2 + 3.14 : cita2;
//    if(cita1 == cita2)
//        return a.first < b.first;
//    else if(cita1 < cita2)
//        return 1;
//    else return 0;
//}
bool cmp3(const pair<double, double>& a, const pair<double, double>& b)
{
    return a.first < b.first;
}

int cross(const pair<double, double> &a, const pair<double, double> &b, const pair<double, double> &c)
{
    return (b.first - a.first) * (c.second - a.second) - (c.first - a.first) * (b.second - a.second);
}

bool cmp2(const pair<double, double>& a, const pair<double, double>& b)
{
    pair<double, double> c;
    c.first = 0;
    c.second = 0;
    if(cross(c, a, b)==0)
        return a.first < b.first;
    else
        return cross(c, a, b) > 0;

}

vector<pair<double, double> > Graham(vector<pair<double, double> > &nums, int l, int r)
{
    vector<pair<double, double> > ret;
    // 边界条件
    if(l > r)
        return ret;

    if(r - l + 1 <= 3)
    {
        for(int i = l; i <= r; i++)
            ret.push_back(nums[i]);
        return ret;
    }

    // 划分、递归
    int m = (l + r) / 2;
    vector<pair<double, double> > ret1 = Graham(nums, l, m);
    vector<pair<double, double> > ret2 = Graham(nums, m + 1, r);
    vector<pair<double, double> > temp;
    for(int i = 0; i < ret1.size(); i++)
        temp.push_back(ret1[i]);
    for(int i = 0; i < ret2.size(); i++)
        temp.push_back(ret2[i]);

    // 求最小y的点point,用了个排序
    sort(temp.begin(), temp.end(), cmp1);
    double x = temp[0].first, y = temp[0].second;
    // 将所有的点移动到point为原点的坐标系下
    for(int i = 0; i < temp.size(); i++)
    {
        temp[i].first -= x;
        temp[i].second -= y;
    }
    // 按极角排序
    sort(temp.begin() + 1, temp.end(), cmp2);


    ret.push_back(temp[0]);
    ret.push_back(temp[1]);
    ret.push_back(temp[2]);
    // 遍历剩余结点,如果当前结点不在上一个结点的逆时针方向,则移除上一个结点,直至符合
    for(int i = 3; i < temp.size(); i++)
    {
        while(ret.size() >= 2 && cross(ret[ret.size() - 2], ret[ret.size() - 1], temp[i]) <= 0)
            ret.pop_back();
        ret.push_back(temp[i]);
    }
    for(int i = 0; i < ret.size(); i++)
        ret[i].first += x, ret[i].second += y;
    return ret;
}


int main()
{
    int isborder[101][101];
    memset(isborder, 0, sizeof(isborder));
    vector<pair<double, double> > nums;
    cin >> n;
    if(n < 3)
    {
        cout << "Points not enough" << endl;
        return 0;
    }

    for(int i = 0; i < n; i++)
    {
        double x, y;
        cin >> x >> y;
        isborder[(int)x][(int)y] = -1;
        nums.push_back(pair<double, double> (x, y));
    }
    clock_t startTime, endTime;
    startTime = clock();
    // 先将所有的点按x排序,这样简便划分
    sort(nums.begin(), nums.end(), cmp3);

    vector<pair<double, double> > ret = Graham(nums, 0, nums.size() - 1);
    endTime = clock();

    cout << "result: " << endl;
    for(int i = 0; i < ret.size(); i++)
    {

        cout << ret[i].first << " " << ret[i].second << endl;
        isborder[(int)ret[i].first][(int)ret[i].second] = 1;
    }
    for(int i = 0; i <= 100; i++)
    {
        for(int j = 0; j <= 100; j++)
        {
            if(isborder[i][j] == -1)
                cout << "6";
            else if(isborder[i][j] == 0)
                cout << "*";
            else
                cout << "7";
        }
        cout << endl;

    }




    cout << "The run time is: " <<(double)(endTime - startTime) << "ms" << endl;


    return 0;
}
View Code

 

标签:const,temp,nums,second,算法,哈工大,2022,pair,first
来源: https://www.cnblogs.com/WTSRUVF/p/16350512.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有