动态规划练习一:n条直线的交点个数
大体意思是这样的,这里有n条直线,问这n条直线的交点有多少种情况,不考虑三条和三条以上直线交与一点的情况,即所有的交点都是二条直线相交得到的。
题目的分析情况详细可参见杭电刘老师动态规划的讲义,大体意思就是先从n条直线中任选出一条直线,以这条直线为标准,把剩余的n-1条直线分为两类,一类就是与所选直线平行的直线,另一类就是与所选直线不平行的直线。
n条直线的交点个数 = 第一类中直线的交点个数(0) + 第二类中的交点个数(已保存) + 两类直线相互的交点(两类直线个数的乘积)。
不再详细讲述了。
代码如下:
题目的分析情况详细可参见杭电刘老师动态规划的讲义,大体意思就是先从n条直线中任选出一条直线,以这条直线为标准,把剩余的n-1条直线分为两类,一类就是与所选直线平行的直线,另一类就是与所选直线不平行的直线。
n条直线的交点个数 = 第一类中直线的交点个数(0) + 第二类中的交点个数(已保存) + 两类直线相互的交点(两类直线个数的乘积)。
不再详细讲述了。
代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<vector<int>> crossnode; //用来存放所有的数据
vector<int> ivec; //用来存放n条直线交点的情况
vector<int> ivec_temp; //临时vector<int>变量
int current_n; //当前crossnode中存放的已经计算完毕的直线交点情况的个数
int parr_i,cross_i; //分别存放平行直线和非平行直线的个数
int new_n; //当前要计算的new_n条直线的交点情况
int cross_num,i; //中间变量
vector<int>::iterator it; //中间变量
int n; //用户的输入
ivec.clear();
ivec.push_back(0);
crossnode.push_back(ivec); //n = 0时的交点情况
crossnode.push_back(ivec); //n = 1时的交点情况
ivec.clear();
ivec.push_back(0);
ivec.push_back(1);
crossnode.push_back(ivec); //n = 2时的交点情况
current_n = 2; //置当前crossnode中已经存放了n <= 2时的所用情况
while(cin>>n&&n != -1)
{
if(n <= current_n) //当前数据结构crossnode中已经计算完毕
{
ivec = crossnode[n];
for(i = 0;i < ivec.size();++i)
cout<<ivec[i]<<" ";
cout<<endl;
}
else //当前的数据结构中还没有计算用户所要求的n条直线的交点情况,需要从current_n开始计算
{
while(current_n < n)
{
ivec.clear();
new_n = current_n + 1; //根据current_n条直线的交点情况计算new_n条直线的交点情况
//parr_i代表相互平行的直线条数(前提是从现有的new_n条直线中先任选出一条直线),这就决定了parr_i的取值范围
for(parr_i = new_n;parr_i > 1;--parr_i)
{
//除去平行直线外的非平行直线(注:此处的非平行是相对于前面的任选出的那条直线而言的)
cross_i = new_n - parr_i;
ivec_temp = crossnode[cross_i];
for(i = 0;i < ivec_temp.size();++i)
{
cross_num = parr_i*cross_i+ivec_temp[i];
ivec.push_back(cross_num);
}
}
ivec.push_back(new_n*(new_n-1)/2); //当new_n条直线中没有互相平行的直线时交点个数
sort(ivec.begin(),ivec.end());
it = unique(ivec.begin(),ivec.end()); //除去重复元素
ivec.erase(it,ivec.end());
crossnode.push_back(ivec);
current_n++;
}
ivec = crossnode[n];
for(i = 0;i < ivec.size();++i)
cout<<ivec[i]<<" ";
cout<<endl;
}
}
return 0;
}
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<vector<int>> crossnode; //用来存放所有的数据
vector<int> ivec; //用来存放n条直线交点的情况
vector<int> ivec_temp; //临时vector<int>变量
int current_n; //当前crossnode中存放的已经计算完毕的直线交点情况的个数
int parr_i,cross_i; //分别存放平行直线和非平行直线的个数
int new_n; //当前要计算的new_n条直线的交点情况
int cross_num,i; //中间变量
vector<int>::iterator it; //中间变量
int n; //用户的输入
ivec.clear();
ivec.push_back(0);
crossnode.push_back(ivec); //n = 0时的交点情况
crossnode.push_back(ivec); //n = 1时的交点情况
ivec.clear();
ivec.push_back(0);
ivec.push_back(1);
crossnode.push_back(ivec); //n = 2时的交点情况
current_n = 2; //置当前crossnode中已经存放了n <= 2时的所用情况
while(cin>>n&&n != -1)
{
if(n <= current_n) //当前数据结构crossnode中已经计算完毕
{
ivec = crossnode[n];
for(i = 0;i < ivec.size();++i)
cout<<ivec[i]<<" ";
cout<<endl;
}
else //当前的数据结构中还没有计算用户所要求的n条直线的交点情况,需要从current_n开始计算
{
while(current_n < n)
{
ivec.clear();
new_n = current_n + 1; //根据current_n条直线的交点情况计算new_n条直线的交点情况
//parr_i代表相互平行的直线条数(前提是从现有的new_n条直线中先任选出一条直线),这就决定了parr_i的取值范围
for(parr_i = new_n;parr_i > 1;--parr_i)
{
//除去平行直线外的非平行直线(注:此处的非平行是相对于前面的任选出的那条直线而言的)
cross_i = new_n - parr_i;
ivec_temp = crossnode[cross_i];
for(i = 0;i < ivec_temp.size();++i)
{
cross_num = parr_i*cross_i+ivec_temp[i];
ivec.push_back(cross_num);
}
}
ivec.push_back(new_n*(new_n-1)/2); //当new_n条直线中没有互相平行的直线时交点个数
sort(ivec.begin(),ivec.end());
it = unique(ivec.begin(),ivec.end()); //除去重复元素
ivec.erase(it,ivec.end());
crossnode.push_back(ivec);
current_n++;
}
ivec = crossnode[n];
for(i = 0;i < ivec.size();++i)
cout<<ivec[i]<<" ";
cout<<endl;
}
}
return 0;
}
我没有什么雄心壮志,我只想给自己和关心自己的家人和朋友一个交代,仅此而已。