[BZOJ1800][Ahoi2009]fly 飛行棋 暴力枚舉
阿新 • • 發佈:2018-09-27
space div jpg clu nbsp 數學 code NPU solution
1
2
2
3
1
1
3
3
Description
給出圓周上的若幹個點,已知點與點之間的弧長,其值均為正整數,並依圓周順序排列。 請找出這些點中有沒有可以圍成矩形的,並希望在最短時間內找出所有不重復矩形。Input
第一行為正整數N,表示點的個數,接下來N行分別為這N個點所分割的各個圓弧長度Output
所構成不重復矩形的個數Sample Input
81
2
2
3
1
1
3
3
Sample Output
3HINT
N<= 20
Solution
第一反應,$n$這麽小,狀壓?
再結合圖看了一下,就是道水題...
做法:暴力枚舉
四重或者二重都行。我寫了個四重的
枚舉四個邊,然後回憶一下初中數學初二內容,一個矩形的判定條件是對邊相等,然後四個角是直角。(這裏不用判直角,只要對邊相等就行了)
所以枚舉$i,j,k,l$,左上、右上,右下,左下。
在這之前預處理一下每個點到其他點的距離(順時針)以及整個圓的周長
判定條件就是$a[ i ][ j ] == a[ k ][ l ]$且$a[ j ][ k ] == sum - a[ i ][ l ]$
#include <bits/stdc++.h> using namespace std ; int n ; int a[ 50 ][ 50 ] ; int main() { int sum = 0 ; scanf( "%d" , &n ) ; for( int i = 1; i <= n ; i ++ ) { scanf( "%d" , &a[ i ][ i + 1 ] ) ; sum += a[ i ][ i + 1 ] ; } for( int i = 1 ; i <= n ; i ++ ) { for( int j = i + 1 ; j <= n ; j ++ ) { a[ i ][ j ] = a[ i ][ j - 1 ] + a[ j - 1 ][ j ] ; } } int ans = 0; for( int i = 1 ; i <= n ; i ++ ) { for( int j = i + 1 ; j <= n ; j ++ ) { for( int k = j + 1 ; k <= n ; k ++ ) { for( int l = k + 1 ; l <= n ; l ++ ) { if( a[ i ][ j ] == a[ k ][ l ] && a[ j ][ k ] == sum - a[ i ][ l ] ) ans ++ ; } } } } printf( "%d\n" , ans ) ; }
[BZOJ1800][Ahoi2009]fly 飛行棋 暴力枚舉