Parallel Lines(Aizu 1379)
阿新 • • 發佈:2018-10-03
line poi nts stream text struct pca lec return
平行直線
題意:給出一些點,這些點兩兩相連成一條直線,問最多能連成多少條直線。
思路:暴力出奇跡!!記得當時比賽做這道題的時候一直依賴於板子,結果卻限制了自己的思路,這得改。dfs直接暴力,但是需要將已經走過的點標記一下,用一個循環跳過已經標記的點減少dfs次數,不然得不出正確的結果,因為會出現如下的連線結果(左圖),而正確的連線方式應該如右圖。
代碼:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <set> 5 #include <cstring> 6View Code#include <queue> 7 #define INF 0x3f3f3f3f 8 #define MIN(a,b) a<b ? a : b 9 #define MAX(a,b) a>b ? a : b//確實要比C++自帶的max函數要快 10 #define FRE() freopen("in.txt","r",stdin) 11 using namespace std; 12 const int maxn = 20; 13 const int MOD = 1e9 + 7; 14 typedef long long ll; 15 typedef pair<int, int> P; 16 struct Point { 17 int x,y; 18 } p[maxn]; 19 struct Line { 20 int x,y; 21 } l[maxn]; 22 int m,ans,cnt,vis[maxn]; 23 24 int upDate() {//遍歷任意兩條邊之間是否平行,更新最大的結果 25 int res = 0; 26 for(int i = 0; i<cnt; i++) 27 for(int j = i+1; j<cnt; j++) { 28 if(l[i].x*l[j].y == l[i].y*l[j].x){//註意有斜率不存在情況,所以要對等式做一下變形 29 res++; 30 } 31 } 32 return res; 33 } 34 35 void dfs(int now) { 36 while(vis[now])//減少dfs次數,同樣也是避免出現之前說的情況 37 now++; 38 if(now == m) { 39 ans = MAX(upDate(),ans); 40 return; 41 } 42 vis[now] = 1; 43 for(int i = 0; i<m; i++) { 44 if(!vis[i] && cnt != i) { 45 l[cnt].x = p[now].x - p[i].x; 46 l[cnt].y = p[now].y - p[i].y; 47 vis[i] = 1; 48 cnt++; 49 dfs(now+1);//枚舉的是每種連接方式下的點的個數 50 cnt--; 51 vis[i] = 0; 52 } 53 } 54 vis[now] = 0; 55 return; 56 } 57 58 59 int main() { 60 memset(vis,0,sizeof(vis)); 61 scanf("%d",&m); 62 for(int i = 0; i<m; i++) { 63 scanf("%d%d",&p[i].x,&p[i].y); 64 } 65 ans = 0; 66 cnt = 0; 67 dfs(0); 68 printf("%d\n",ans); 69 return 0; 70 }
Parallel Lines(Aizu 1379)