C++ n条直线,无三线共点,能有多少种不同的交点数(动态规划)

一、题目描述

     C++ n条直线,无三线共点,能有多少种不同的交点数(动态规划)_第1张图片

二、思路:

    问题分析:(1)直线2与直线1,最多只有1个交点;

    (2)直线3,与直线1、2最多有2个交点;

      ……

    (3)直线n,与其他的n-1条直线最多有n-1个交点

      归纳:n条直线互不平行且无三线共点的交点数最多为:Max = 1 +2 +……+(n-1)=n(n-1)/2;

 

   n条直线有多少种不同的交点数(n只考虑大于1)

   (1)当n==2时 

           A.当2条直线平行时,交点数为0;

           B.当2条直线相交时,交点数为:1 *(2-1)+ 0 = 1 ;

   (2)当n==3时,

           A.当3条直线平行时,交点数为0;

           B.当2条直线平行时,交点数为:2 *(3-2)+ 0 = 2;

           C.当没有直线平行时,交点数为:1 *(3-1)+ 1 = 3;

    (3)当n==4时,

            A.四条直线全部平行,无交点;

            B.其中3条直线平行,交点数为:3 *(4-3)+ 0 = 3;

            C.其中2条直线平行,另外2条直线可能平行或相交:

               2*(4-2)+ 0 = 4; (另两条直线平行)

               2*(4-2)+ 1 =  5;(另两条直线相交)

            D.没有直线平行,交点数为:1*(n-1) + {3条直线的相交情况}

                1*(n-1)+0=3 

                1*(n-1)+2=5 

                1*(n-1)+3=6

            综上:

            n条直线的交点数 = r条平行线*(剩下的n-r条直线)+(剩下的n-r条直线的交点数)

 

三、实现程序:

//  main.cpp
//  nLines:n条直线,无三线共点,能有多少种不同的交点数(动态规划)
//  n条直线互不平行且无三线共点的交点数最多为:Max = 1 +2 +……+(n-1)=n(n-1)/2;
//  n条直线的交点数 = r条平行线*(剩下的n-r条直线)+(剩下的n-r条直线的交点数)
//  arr[n][j]表示n条直线,交点数为j
//  Created by ChanJose on 2019/1/16.
//  Copyright © 2019年 ChanJose. All rights reserved.
//

#include 
using namespace std;

int main(int argc, const char * argv[])
{
    // arr[n][j]表示n条直线,交点数为j
    int arr[21][200], n; //  2<=n<=20条直线,最多有:20*(20-1)/2=190
    int i, j, a, b;
    
    memset(arr, 0, sizeof(arr)); // 清零
    arr[0][0] = arr[1][0] = 1; // 表示0条或1条直线情况,后面动态规划中b==1时要用到
    for(n = 2; n < 21; n++) // n:表示n条直线
    {
        //不管多少直线都存在0个交点的情况,即所有直线平行
        arr[n][0] = 1;
        for(i = 1; i < n; i++) // i:表示n条直线中有i条直线平行
        { // i至少有1条直线平行,此时表示没有直线平行。n条直线平行的情况已经考虑了,无需重复
            a = i; // 表示i条直线平行
            b = n - i; // 除i条平行直线剩下的其他直线
            for(j = 0; j <= b * (b - 1) / 2; j++) // b条直线最多有b * (b - 1) / 2个交点数
            { // j表示交点数
                if(arr[b][j]) // 如果b条直线中有j个交点数
                    arr[n][a*b+j] = 1; // a*b+j用了公式 -> n条直线的交点数 = r条平行线*(剩下的n-r条直线)+(剩下的n-r条直线的交点数),这里用了动态规划的思想:根据记录的子问题,解决上一级问题,避免重复计算,自底向上
            }
        }
    }
    cout << "请输入直线的条数n:";
    while(cin >> n)
    {
        cout << n << "条直线的交点数分别为:" << endl;
        for(i = 0; i <= n * (n - 1) / 2; i++)
        {
            if(i == 0) // 所有直线不平行
                cout << i;
            else if(arr[n][i])
                cout << " " << i; // 格式化输出
        }
        cout << endl;
        cout << "请输入直线的条数n:";
    }
    
    return 0;
}

测试结果:

C++ n条直线,无三线共点,能有多少种不同的交点数(动态规划)_第2张图片   

你可能感兴趣的:(数据结构)