http://codeforces.com/gym/101055/problem/A
题目:给定一些三维空间的点,要你找一个平面,能覆盖尽量多的点,只要求输出点数即可。n<=50
因为数据量小,我们考虑暴力。
首先,三个不在同一条直线的点,确定一个平面,然后枚举其他的点。判断一下,这样的复杂度是n^4。可以接受
特判。所有点都在同一条直线。直接输出n、
后面的,枚举三个点后,能算出这个平面的法向量,然后枚举其他点,与法向量的数量积是0的,就可以ans++
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int maxn = 50+20; struct coor { int x,y,z;//坐标,也可以表示成向量,向量也是一个坐标表示嘛 coor(){} coor(int xx,int yy,int zz):x(xx),y(yy),z(zz){} bool operator &(coor a) const //判断两个向量是否共线,共线返回true { //思路:判断叉积,是否各项系数都是0 return (y*a.z - z*a.y)==0 && (z*a.x - x*a.z)==0 && (x*a.y - y*a.x)==0; } coor operator ^(coor a) const //得到两个向量的叉积(就是向量积),返回的是一个向量(坐标) { return coor(y*a.z - z*a.y,z*a.x - x*a.z,x*a.y - y*a.x); } coor operator -(coor a) const //如果是c-d的话,得到向量dc, { return coor(x-a.x,y-a.y,z-a.z); } int operator *(coor a) const //得到两个向量的 数量积,返回整数即可 { return x*a.x+y*a.y+z*a.z; } }a[maxn]; bool all_in_Aline(int n) { //思路,暴力枚举,每三个点,看看是不是所有叉积都是0 for (int i=1;i<=n;++i) //这个作为起点吧 for (int j=i+1;j<=n;++j) for (int k=j+1;k<=n;++k) { coor t1 = a[k]-a[i]; coor t2 = a[j]-a[i]; if (t1&t2) continue; return false; } return true; } bool checkThree (coor a,coor b,coor c) { return (b-a)&(c-a); } void work () { int n; cin>>n; for (int i=1;i<=n;++i) cin>>a[i].x>>a[i].y>>a[i].z; if (all_in_Aline(n)) //如果都在同一直线,直接判断即可 { cout<<n<<endl; return ; } int ans=3; for (int i=1;i<=n;++i) for (int j=i+1;j<=n;++j) for (int k=j+1;k<=n;++k) { if (checkThree(a[i],a[j],a[k])) continue; int t=3; coor t1 = (a[k]-a[i])^(a[j]-a[i]); //垂直的向量 for (int h=1;h<=n;++h) { if (h==i||h==j||h==k) continue; if ((a[h]-a[i])*t1 == 0) t++; } ans = max(ans,t); } cout<<ans<<endl; return ; } int main() { #ifdef local freopen("data.txt","r",stdin); #endif work(); return 0; }
时间: 2024-11-04 12:48:00