您的位置:首页 > 理论基础 > 数据结构算法

2018年北京邮电大学数据结构与算法第一次作业 问题A

2018-03-15 11:31 351 查看
Problem A:



题目描述:

在二维平面上,横轴上随意摆放着若干数目大小不一的正方形,这些正方形底边均与横轴重合,正方形间可能有重叠。

输入:

第一行为正方形总数目

第二行 每两个数为一组,即一个正方形的左右边缘坐标

输出:

所有正方形围成的外轮廓与横轴所围的面积

样例输入:

5

1 3 2 5 4 6 8 10 9 12

样例输出:

24

一开始拿到这个题,我的思路是:最宽域长×最高域长-所有空白面积

事实上这个思路是很麻烦的,以下是我一开始的算法设计思路:

1.将正方形左坐标从小到大排序

2.从第一个开始,遍历比较该正方形与其后正方形,判断是否交叉……返回所有交叉正方形序号、坐标并储存

3.判断这些正方形是否被包含,被包含正方形剔除之

4.计算出各交叉域,匹配该域属于的最高正方形

5.计算各非交叉域,匹配该域属于的最高正方形

6.求面积

然而这个思路硬伤太大,乍看没问题,但其实只要一往细节处考虑,就原地爆炸了。其最主要的问题是,在处理“多个正方形共同交叉,有三层以上的交叉域存在”这样的情况时,根本就没办法处理。其次另一个问题是,两个正方形群落间的空白地区难以甄别并处理。

所以我尝试未果后,干净利落地放弃了这个思路。

但是基于这个思路,我修改了一下对数据的处理行为。类比微积分的定义,在正方形边长只能是1的倍数的时候,我们可以将整个所求图形分割为一个个底边为1的长方形条块,逐个求面积,并加和。

于是有了这个思路:分割、逐个求面积、求和

算法设计思路:

1.将正方形左坐标从小到大排序 Sq_Vessel[]

2.将正方形坐标排序,形成各域 Region_Vessel[]

3.按1中序,排列正方形边长 Sq_SideLenth[]

4.设计函数Match(),可以将域与所属最高正方形匹配

5.申请M_R_Vessel[]数组,储存各:域长、所属最高正方形边长

6.求积、求和

以下是C++的程序实现:(Debug痕迹我没有删除……)

#include<iostream>
using namespace std;
void Sort_Sq(int *&a, int size)
{
for (int i = 0; i < size; i += 2)
for (int j = i + 2; j < size; j += 2)
if (a[i] > a[j])
{
a[i] ^= a[j];
a[i+1] ^= a[j+1];
a[j] ^= a[i];
a[j + 1] ^= a[i + 1];
a[i] ^= a[j];
a[i + 1] ^= a[j + 1];
}
}
void Sort_P(int *&a, int size)
{
int temp = 0;
for (int i = 0; i < size - 1; i++)
for (int j = i + 1; j < size; j++)
if (a[i] > a[j])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
/*bool IfZero(int *&temp, int num)
{
for (int i = 0; i < num; i++)
{
if (temp[i] != 0)
return false;
}
return true;
}*/
void Match(int *&M_R_Vessel, int *&Sq_Vessel, int*&Region_Vessel,int num)
{
//for (int i = 0; i < 2*num; i++)
//  cout << Sq_Vessel[i] << " ";
//cout << endl;
//for (int i = 0; i < 2*num; i++)
//  cout << Region_Vessel[i] << " ";
//cout << endl;
int count = 0;
int count2 = 0;
int Temp = 0;
int *temp = new int[num];
for (int q = 0; q < num; q++)temp[q] = 0;
for (int i = 0; i < 2 * num - 1; i++)
{
for (int j = 0; j < 2 * num - 1; j += 2)
{
if (Region_Vessel[i] >= Sq_Vessel[j] && Region_Vessel[i + 1] <= Sq_Vessel[j + 1])
{
temp[count] = Sq_Vessel[j + 1] - Sq_Vessel[j];
count++;
}
}
if (temp[0]!=0)
{
for (int x = 0; x < count-1; x++)
for (int y = x + 1; y < count; y++)
if (temp[x] < temp[y])
{
Temp = temp[x];
temp[x] = temp[y];
temp[y] = Temp;
}
//cout << temp[0] << endl;
count = 0;
M_R_Vessel[count2] = Region_Vessel[i + 1] - Region_Vessel[i];
//cout << Region_Vessel[i + 1] << endl;
//cout << Region_Vessel[i ] << endl;
//cout << M_R_Vessel[count2] << endl;
M_R_Vessel[count2 + 1] = temp[0];
//cout << M_R_Vessel[count2] << endl;
count2 += 2;
}
else
{
M_R_Vessel[count2] = Region_Vessel[i + 1] - Region_Vessel[i];
M_R_Vessel[count2 + 1] = 0;
count2 += 2;
}
for (int q = 0; q < num; q++)temp[q] = 0;
}
delete[]temp;
}
int Add(int *&M_R_Vessel,int size)
{
int Sum = 0;
for (int i = 0; i < size; i += 2)
{
Sum += M_R_Vessel[i] * M_R_Vessel[i + 1];
}
return Sum;
}
int main()
{
int num = 0;
cin >> num;
int size = 2 * num;
int * Sq_Vessel = new int[size];
for (int i = 0; i < size; i++)
cin >> Sq_Vessel[i];
//for (int i = 0; i < size; i++)
//  cout<< Sq_Vessel[i]<<" ";
int * Region_Vessel = new int[size];
for (int i = 0; i < size; i++)
Region_Vessel[i] = Sq_Vessel[i];
Sort_Sq(Sq_Vessel, size);
Sort_P(Region_Vessel , size);

//for (int i = 0; i < size; i++)
//  cout<< Sq_Vessel[i]<<" ";
//cout << endl;
//for (int i = 0; i < size; i++)
//  cout << Region_Vessel[i] << " ";
//cout << endl;

//int * Sq_SideLenth = new int[num];
//Sort_SL(Sq_SideLenth, Sq_Vessel, num);
int * M_R_Vessel = new int[2*size];
Match(M_R_Vessel, Sq_Vessel, Region_Vessel, num);

//for (int i = 0; i < 2*size-2; i++)
//  cout << M_R_Vessel[i] << " ";
//cout << endl;
int Sum = Add(M_R_Vessel, 2*size-2);
cout << Sum << endl;

delete[] Region_Vessel;
delete[] M_R_Vessel;
delete[] Sq_Vessel;
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: