zoukankan      html  css  js  c++  java
  • codeforces 850 A

    codeforces 850 A

    A. Five Dimensional Points

    introduction

    n个点中,是否存在一个点,与另外任意两个点连成的向量,为锐角

    method

    首先在2维的空间中,要让角不为锐角,最多只能存在5个点(四个向量) 。鸽巢原理。在k维空间中,最多只能存在2k+1个节点。k=5时,最多只能存在11个节点。所以:

    • 输出0,如果节点数大于11
    • 枚举,如果节点数小于等于10

    tips

    1. 成角的向量不能随意交换向量的两个端点
    2. 节点数=向量数+ 1
    3. 鸽巢原理是非常有用

    reference

    http://codeforces.com/blog/entry/54317
    https://blog.csdn.net/Fusheng_Yizhao/article/details/78557741
    鸽笼原理 谢聪智

    code

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<cmath>
    #include<map>
    #include<istream>
    #include<ostream>
    #define DEBUG(x) cout<<#x<<" = "<<x<<endl
    #define pi acos(-1)
    using namespace std;
    const int MAXN=1e3+10;
    struct point{
        int a[5];
        point(){memset(a,0,sizeof(a));}
        friend istream & operator>>(istream &in,point &p)
        {
            for(int i=0;i<5 ;i++ ){
                in>>p.a[i];
            }
            return in;
        }
        friend ostream &operator<<(ostream &out,const point &p)
        {
            for(int i=0;i<5 ;i++ ){
                out<<p.a[i]<<" ";
            }
            return out;
        }
    };
    typedef point vec;
    inline vec mkvec(point &p1,point &p2)
    {
        vec v;
        for(int i=0;i<5 ;i++ ){
            v.a[i]=p2.a[i]-p1.a[i];
        }
        return v;
    }
    int n;
    point pts[MAXN];
    int dot(vec &p1,vec &p2)
    {
        int rt=0;
        for(int i=0;i<5 ;i++ ){
            rt+=p1.a[i]*p2.a[i];
        }
        return rt;
    }
    ///根据鸽巢原理可以大幅度降低复杂度
    ///向量是有方向的
    int main()
    {
    //    freopen("in.txt","r",stdin);
        cin>>n;
        for(int i=1;i<=n ;i++ ){
            cin>>pts[i];
        }
        vector<int>ans;
        if(n<3){
            for(int i=1;i<=n ;i++ ){
                ans.push_back(i);
            }
        }
        else if(n<=11)
        for(int i=1;i<=n ;i++ ){
            vector<vec>v;
            for(int j=1;j<=n ;j++ ){
                if(i!=j)
                v.push_back(mkvec(pts[i],pts[j]));
            }
            bool ok=true;
            for(int k=0;k<v.size() ;k++ ){
                for(int u=k+1;u<v.size() ;u++ ){
                    if(dot(v[k],v[u])>0)ok=false;
                }
            }
            if(ok)ans.push_back(i);
        }
        cout<<ans.size()<<endl;
        for(int i=0;i<ans.size() ;i++ ){
            cout<<ans[i]<<endl;
        }
    }
    
  • 相关阅读:
    3Sum Closest
    二叉树的下一个结点
    数组中重复的数字
    不用加减乘除做加法
    和为S的连续正数序列
    数组中只出现一次的数字
    求二叉树的是否为平衡二叉树
    由一道很简单的求两条链表的第一个公共节点的问题引发的思考
    第14章 网络编程
    第13章 文档与串行化
  • 原文地址:https://www.cnblogs.com/MalcolmMeng/p/10195067.html
Copyright © 2011-2022 走看看