[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; }
本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9372581.html