[BZOJ] 1800: [Ahoi2009]fly 飞行棋

https://www.lydsy.com/JudgeOnline/problem.php?id=1800

题意:给出一个圆上n个点,问能组成多少个不同的矩形。

 

注意到数据非常小,可以直接枚举..先断环成链,注意到矩形对边相等,就先枚举一对(i,j),(k,l)使得[i,j]==[k,l],然后再处理剩余区域即可。

还有更好的思路,找到所有len=(sum/2)的边,因为矩形对角线一定是一条直径,所以这样的边找到一对即可,也就是C(s,2),s是相等的个数。

#include<iostream>
#include<cstdio>

using namespace std;

inline int rd(){
    int ret=0,f=1;char c;
    while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
    while(isdigit(c))ret=ret*10+c-'0',c=getchar();
    return ret*f;
}

const int MAXN=64;

int n,ans;
int val[MAXN],a[MAXN],sum[MAXN];

int dis(int x,int y){return sum[y]-sum[x-1];}

void solve(){
    int pos=1,s=0,s2=0;
    for(;pos<=n;pos++){
        s+=a[pos];
        if(s==(sum[n]>>1)) break; 
        if(s>(sum[n]>>1)) return;
    }
    for(int i=1;i<pos;i++){
        for(int j=i;j<pos;j++){
            for(int k=pos+1;k<n;k++){
                for(int l=k;l<n;l++){
                    if(dis(i,j)==dis(k,l)&&dis(0,i-1)+dis(l+1,n)==dis(j+1,k-1)){
                        ans++;
                    }
                }
            }
        }
    }
}

int main(){
    n=rd();
    int fans=0;
    for(int i=1;i<=n;i++) val[i]=val[i+n]=rd();
    for(int i=1;i<=n;i++){
        for(int j=i;j<=i+n;j++){
            a[j-i+1]=val[j];
            sum[j-i+1]=sum[j-i]+val[j];
        }
        solve();    
        fans=max(fans,ans);ans=0;
    }
    cout<<fans;

    return 0;
}

 

posted @ 2018-07-26 16:31  GhostCai  阅读(75)  评论(0编辑  收藏  举报