原题网址:bzoj P1800
题目描述
给出圆周上的若干个点,已知点与点之间的弧长,其值均为正整数,并依圆周顺序排列。 请找出这些点中有没有可以围成矩形的,并希望在最短时间内找出所有不重复矩形。
输入
第一行为正整数N,表示点的个数,接下来N行分别为这N个点所分割的各个圆弧长度
输出
所构成不重复矩形的个数
样例输入
8
1
2
2
3
1
1
3
3
样例输出
3
提示
N<= 20 ,所有数字均不大于200
首先,看一下题目。注意数据范围,非常的小,也就是说,这一道题目可以直接暴力求解。
接下来,分析数据,发现输入的仅仅是每一段的长度,所以,为了方便,需要开一个数组来保存所有点距离原点的距离(顺时针)。其实就是前缀和。
接下来,直接for循环(四重)暴力求解O(n4)算法,虽然有更加快的算法,比如说O(n2)算法,只需要枚举其中两个点,然后判断另外两个节点是否存在即可。此外,搜索的方法要注意,不能有重复,或者在最后面除以4即可。
献上AC代码:
#include<cstdio>
using namespace std;
int sum,a[39],n,x,ans=0;
int abs(int x){
if(x<0) return -x;
else return x;
}
int getS(int x,int y){
if(abs(x-y)<sum/2)
return abs(x-y);
else if(x>y)
return sum-x+y;
else return sum-y+x;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&x);
a[i]=a[i-1]+x;
}
sum=a[n];
for(int i=1;i<=n-3;i++)
for(int j=i+1;j<=n-2;j++)
for(int k=j+1;k<=n-1;k++)
for(int l=k+1;l<=n;l++)
if(getS(a[i],a[j])==getS(a[k],a[l])&&getS(a[j],a[k])==getS(a[l],a[i]))
ans++;
printf("%d",ans);
return 0;
}