动态规划练习一:n条直线的交点个数

   大体意思是这样的,这里有n条直线,问这n条直线的交点有多少种情况,不考虑三条和三条以上直线交与一点的情况,即所有的交点都是二条直线相交得到的。
题目的分析情况详细可参见杭电刘老师动态规划的讲义,大体意思就是先从n条直线中任选出一条直线,以这条直线为标准,把剩余的n-1条直线分为两类,一类就是与所选直线平行的直线,另一类就是与所选直线不平行的直线。
n条直线的交点个数 = 第一类中直线的交点个数(0) + 第二类中的交点个数(已保存) + 两类直线相互的交点(两类直线个数的乘积)。
不再详细讲述了。
代码如下:
#include  < iostream >
#include 
< vector >
#include 
< algorithm >
using   namespace  std;
int  main()
ExpandedBlockStart.gifContractedBlock.gif
{
    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&&!= -1)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
if(n <= current_n) //当前数据结构crossnode中已经计算完毕
ExpandedSubBlockStart.gifContractedSubBlock.gif
        {
            ivec 
= crossnode[n];
            
for(i = 0;i < ivec.size();++i)
                cout
<<ivec[i]<<" ";
            cout
<<endl;
        }

        
else //当前的数据结构中还没有计算用户所要求的n条直线的交点情况,需要从current_n开始计算
ExpandedSubBlockStart.gifContractedSubBlock.gif
        {
            
while(current_n < n)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                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) 
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
//除去平行直线外的非平行直线(注:此处的非平行是相对于前面的任选出的那条直线而言的)
                    cross_i = new_n - parr_i; 
                    ivec_temp 
= crossnode[cross_i];
                    
for(i = 0;i < ivec_temp.size();++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        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;
}

转载于:https://www.cnblogs.com/krisdy/archive/2009/09/17/1568424.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值