20分钟一遍AC,大水题,我的算法比较复杂,但是好理解,就是找可以凑出来一半周长的点来暴力枚举就行了。
题干:
Description 给出圆周上的若干个点,已知点与点之间的弧长,其值均为正整数,并依圆周顺序排列。 请找出这些点中有没有可以围成矩形的,并希望在最短时间内找出所有不重复矩形。 Input 第一行为正整数N,表示点的个数,接下来N行分别为这N个点所分割的各个圆弧长度 Output 所构成不重复矩形的个数 Sample Input 8 1 2 2 3 1 1 3 3 Sample Output 3
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(int i = a;i <= n;i++) #define lv(i,a,n) for(int i = a;i >= n;i--) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } int len[25][25]; int a[50]; int n,tot = 0,ans = 0; queue <int> qu; void work(int x,int k) { duke(i,1,k - 1) { int s = len[x][i]; duke(j,k + 1,n) { if(len[x][j] - len[x][k] == s) { ans++; } } } } int main() { read(n); duke(i,1,n) { read(a[i]); a[i + n] = a[i]; tot += a[i]; } tot /= 2; duke(i,1,n) { int ok = 0; duke(j,1,n) { len[i][j] = len[i][j - 1] + a[i + j - 1]; if(len[i][j] == tot) { ok = 1; } } if(ok == 1) qu.push(i); } while(!qu.empty()) { int x = qu.front(); int k; duke(i,1,n) { if(len[x][i] == tot) { k = i; break; } } work(x,k); qu.pop(); } printf("%d ",ans / 4); return 0; } /* 8 1 2 2 3 1 1 3 3 */