1800: [Ahoi2009]fly 飞行棋

1800: [Ahoi2009]fly 飞行棋

 

Description

给出圆周上的若干个点,已知点与点之间的弧长,其值均为正整数,并依圆周顺序排列。 请找出这些点中有没有可以围成矩形的,并希望在最短时间内找出所有不重复矩形。

Input

第一行为正整数N,表示点的个数,接下来N行分别为这N个点所分割的各个圆弧长度

Output

所构成不重复矩形的个数

Sample Input

8
1
2
2
3
1
1
3
3


Sample Output

3

HINT

N<= 20

Source

这道题还是挺水的 想要构成矩形 那么对角线一定是圆的直径  

找到所有圆的直径 判断两组点是否构成矩形 (好像这里是组合数???)

 1 #include <cstdio>
 2 #include <cctype>
 3 #include <cstring>
 4 
 5 const int INF=0x3f3f3f3f;
 6 const int MAXN=110;
 7 
 8 int n,c,tot,ans;
 9 
10 int map[MAXN][MAXN],Sx[MAXN],Sy[MAXN];
11 
12 inline void read(int&x) {
13     int f=1;register char c=getchar();
14     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
15     for(;isdigit(c);x=x*10+c-48,c=getchar());
16     x=x*f;
17 }
18 
19 inline int min(int a,int b) {return a<b?a:b;}
20 
21 inline void DFS() {
22     for(int i=1;i<=tot;++i) 
23       for(int j=1;j<=tot;++j) {
24           if(i==j) continue;
25           int x1=Sx[i],y1=Sy[i];
26           int x2=Sx[j],y2=Sy[j];
27           if(map[x1][x2]==map[y1][y2]&&map[x2][y1]==map[x1][y2]) ++ans;
28       }
29 }
30 
31 int hh() {
32     freopen("A.in","r",stdin);
33     freopen("A.out","w",stdout);
34     read(n);
35     memset(map,INF,sizeof map);
36     for(int i=1;i<n;++i) read(map[i][i+1]),c+=map[i][i+1],map[i+1][i]=map[i][i+1];
37     read(map[n][1]),map[1][n]=map[n][1];
38     c+=map[n][1];
39     for(int k=1;k<=n;++k)
40       for(int i=1;i<=n;++i)
41         for(int j=1;j<=n;++j)
42           map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
43     for(int i=1;i<=n;++i)
44       for(int j=1;j<=n;++j)
45           if(map[i][j]==c/2) {
46               Sx[++tot]=i,Sy[tot]=j;
47               break;
48         }
49     tot/=2;
50     DFS();
51     printf("%d
",ans/2);
52     fclose(stdin);
53     fclose(stdout);
54     return 0;
55 }
56 
57 int sb=hh();
58 int main(int argc,char**argv) {;}
代码
原文地址:https://www.cnblogs.com/whistle13326/p/7568467.html