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; }
枚举边,一条边构成的正方形只有两种情况,确定了一条边,另外两个点的坐标只能是(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; }
D题:线段树。。待补充。。。。。
看来这段时间在刷专题的同时得抽出时间每天打cf了。。不然碰到思维题又死机了。。。。
没有AC不了的题,只有不努力的ACMER!