fly 飞行棋 题解

原题网址:bzoj P1800

题目描述
给出圆周上的若干个点,已知点与点之间的弧长,其值均为正整数,并依圆周顺序排列。 请找出这些点中有没有可以围成矩形的,并希望在最短时间内找出所有不重复矩形。
输入
第一行为正整数N,表示点的个数,接下来N行分别为这N个点所分割的各个圆弧长度
输出
所构成不重复矩形的个数
样例输入
8
1
2
2
3
1
1
3
3

样例输出
3

提示
N<= 20 ,所有数字均不大于200
fly 飞行棋 题解
首先,看一下题目。注意数据范围,非常的小,也就是说,这一道题目可以直接暴力求解。
接下来,分析数据,发现输入的仅仅是每一段的长度,所以,为了方便,需要开一个数组来保存所有点距离原点的距离(顺时针)。其实就是前缀和
接下来,直接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;
}
上一篇:Python之Numpy库


下一篇:java代码覆盖实战