HDOJ-----1466---計算直線的交點數---動態規劃

計算直線的交點數

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9789    Accepted Submission(s): 4461


Problem Description
平面上有n條直線,且無三線共點,問這些直線能有多少種不同交點數。
比如,如果n=2,則可能的交點數量爲0(平行)或者1(不平行)。
 

Input
輸入數據包含多個測試實例,每個測試實例佔一行,每行包含一個正整數n(n<=20),n表示直線的數量.
 

Output
每個測試實例對應一行輸出,從小到大列出所有相交方案,其中每個數爲可能的交點數,每行的整數之間用一個空格隔開。
 

Sample Input
2 3
 

Sample Output
0 1 0 2 3

n條直線的交點可以看作i條平行線與n-i條直線相交,類似於上樓梯一次可以走兩步或一步,第n階可以由前兩階得出,n條直線交點由前n-1條直線交點得到
i條直線,j條平行線的交點數爲=i*(i-j)+(i-j)條直線所有的交點情況

n條直線所有的相交情況一共n*(n-1)/2種,兩兩相交沒有三點一線,每兩點都有交點,由組合數得出,數據量爲20,所以最大200種情況

#include<cstdio>
#include<iostream>
#include<cstring>
#define LL long long
using namespace std;
bool s[25][250];//s[i][j]表示i條直線,j個交點的情況是否存在
void solve(){
	memset(s, false, sizeof(s));
	for(int i = 1; i <= 20; i++) s[i][0] = true;//不論幾條直線,全部平行即0個交點肯定存在
	for(int i = 2; i <= 20; i++){//n條直線的情況
		for(int j = 1; j <= i; j++){//j條平行線
			for(int k = 0; k < 200; k++){//最多200種交點情況
				if(s[i-j][k]) s[i][k+j*(i-j)] = true;//i條直線,去掉j條平行線,即i-j條線是否存在k個交點的情況,若i-j存在則i也存在
			}
		}
	}
}
int main(){
	int t;
	solve();
	while(cin >> t){
		cout << 0;
		for(int i = 1; i <= t*(t-1)/2; i++){
			if(s[t][i]) cout << ' ' << i;
		}
		cout << endl;
	}
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章