洛谷P2665 [USACO08FEB]连线游戏Game of Lines

一、算法分析

本题上来先想到的就是爆搜一下,结果tle两个点。后仔细看题,原来只要求出所有斜率的可能,每种斜率各一条直线,就可以得到答案。注意对斜率的计算一定要对分母为0的情况进行特判。

二、暴搜代码(tle两个点)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#define ll long long
using namespace std;
const int maxn=1005;
int n;
struct point{
  int x;
  int y;
  point(int u,int v):x(u),y(v){}
};
vector<point> a;
map<double,bool> mp;                 //判断斜率是否重复(即判断新连接的线与已有直线是否平行) 
ll ans=0;
void dfs(int cur){
	if(cur==n) return;
	for(int i=0;i<n;i++){              //尝试连接其它点 
		if(cur==i) continue;             
		double k;
		if(a[cur].x!=a[i].x)             //注意要特判一下直线与x轴垂直的情况
		  k=(double)(a[cur].y-a[i].y)/(double)(a[cur].x-a[i].x);
		else k=1000000000;
		if(!mp[k]){
			mp[k]=true;
			ans++;
			dfs(cur+1);
		}
	}
} 
int main(){ 

  int xx,yy;
  cin>>n;
  for(int i=0;i<n;i++){
  	cin>>xx>>yy;
  	a.push_back(point(xx,yy));
	}
  dfs(0);
  cout<<ans;
	return 0;
}

三、AC代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<set>
#include<cmath>
#define ll long long
using namespace std;
const int maxn=1005;
int n;
struct point{
  int x;
  int y;
  point(int u,int v):x(u),y(v){}
};
vector<point> a;
double xielv(point p1,point p2){
	double k;
	if(p1.x!=p2.x)             //注意要特判一下直线与x轴垂直的情况
		k=(double)(p1.y-p2.y)/(double)(p1.x-p2.x);
	else k=1000000000;
	return k;
}
int ans=0;
set<double> setti;
int main(){ 
  
  int xx,yy;
  cin>>n;
  for(int i=0;i<n;i++){
  	cin>>xx>>yy;
  	a.push_back(point(xx,yy));
	}
  for(int i=0;i<n-1;i++)
    for(int j=i+1;j<n;j++){
    	setti.insert(xielv(a[i],a[j]));
		}
	ans=setti.size();
  cout<<ans;
	return 0;
}

发布了50 篇原创文章 · 获赞 7 · 访问量 1120

猜你喜欢

转载自blog.csdn.net/numb_ac/article/details/103995552