bestcoder#50

bestcoder#50

A题:水题。注意只有一个的情况。

C题:递推水题。f[n]=f[n-1]+f[n-3]+1。

B题:

给定一些整点,判断这些整点组成的正三,四,五,六边形的个数,数据范围很小。

整点只能组成正四边形,因此直接暴力枚举所有的四个点能否组成正方形就行了,然后重复的情况主要出现在四个点的顺序,每个点有顺时针和逆时针,因此最后除以8就行了。

复杂度o(n^4)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<math.h>
#include<cctype>
#define ll long long
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t))
#define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t))
#define PII pair<int,int>
#define fst first
#define snd second
#define MP make_pair
#define PB push_back
#define RI(x) scanf("%d",&(x))
#define RII(x,y) scanf("%d%d",&(x),&(y))
#define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))
#define DRI(x) int (x);scanf("%d",&(x))
#define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y))
#define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z))
#define RS(x) scanf("%s",x)
#define RSS(x,y) scanf("%s%s",x,y)
#define DRS(x) char x[maxn];scanf("%s",x)
#define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y)
#define MS0(a) memset((a),0,sizeof((a)))
#define MS1(a) memset((a),-1,sizeof((a)))
#define MS(a,b) memset((a),(b),sizeof((a)))
#define ALL(v) v.begin(),v.end()
#define SZ(v) (int)(v).size()

using namespace std;

const int maxn=1000100;
const int INF=(1<<29);
const double EPS=0.0000000001;
const double Pi=acos(-1.0);

struct Point
{
    int x,y;
    friend Point operator-(Point A,Point B)
    {
        Point res;
        res.x=A.x-B.x;
        res.y=A.y-B.y;
        return res;
    }
    friend int operator*(Point A,Point B)///点乘
    {
        return A.x*B.x+A.y*B.y;
    }
};
int n;
Point p[maxn];

int dist(Point A,Point B)
{
    int tx=A.x-B.x,ty=A.y-B.y;
    return tx*tx+ty*ty;
}

bool judge(Point A,Point B,Point C,Point D)
{
    if((B-A)*(C-B)==0&&(C-B)*(D-C)==0&&(D-C)*(A-D)==0&&(A-D)*(B-A)==0){
        int d1=dist(A,B);
        int d2=dist(B,C);
        int d3=dist(C,D);
        int d4=dist(D,A);
        if(d1==d2&&d2==d3&&d3==d4&&d4==d1) return 1;
    }
    return 0;
}

int main()
{
    freopen("in.txt","r",stdin);
    while(~RI(n)){
        REP(i,1,n) RII(p[i].x,p[i].y);
        ll ans=0;
        REP(i,1,n){
            REP(j,1,n){
                if(j==i) continue;
                REP(k,1,n){
                    if(k==j||k==i) continue;
                    REP(q,1,n){
                        if(q==k||q==j||q==i) continue;
                        if(judge(p[i],p[j],p[k],p[q])){
                            ans++;
                        }
                    }
                }
            }
        }
        cout<<ans/8<<endl;
    }
    return 0;
}
View Code

枚举边,一条边构成的正方形只有两种情况,确定了一条边,另外两个点的坐标只能是(x1+ty,y1-tx)(x2+ty,y2-tx)或(x1-ty,y1+tx)(x2-ty,y2+tx)。

判断点是否出现就行了。

复杂度o(n^2)

struct Point
{
    int x,y;
};
Point p[maxn];
int n;
bool vis[120][120];

int main()
{
    freopen("in.txt","r",stdin);
    while(~RI(n)){
        MS0(vis);
        REP(i,1,n) RII(p[i].x,p[i].y),vis[p[i].x][p[i].y]=1;
        int ans=0;
        REP(i,1,n){
            REP(j,1,n){
                if(i==j) continue;
                Point A=p[i],B=p[j];
                int tx=A.x-B.x;
                int ty=A.y-B.y;
                Point C={A.x-ty,A.y+tx};
                Point D={B.x-ty,B.y+tx};
                if(vis[C.x][C.y]&&vis[D.x][D.y]) ans++;
                Point E={A.x-ty,A.y+tx};
                Point F={B.x-ty,B.y+tx};
                if(vis[E.x][E.y]&&vis[F.x][F.y]) ans++;

            }
        }
        cout<<ans/8<<endl;
    }
    return 0;
}
View Code

 

D题:线段树。。待补充。。。。。

看来这段时间在刷专题的同时得抽出时间每天打cf了。。不然碰到思维题又死机了。。。。

 

posted @ 2015-08-08 23:46  __560  阅读(360)  评论(0编辑  收藏  举报