湖南大學ACM程序設計新生杯大賽(同步賽)A - Array
阿新 • • 發佈:2017-12-24
ons arr algo mes 暴力 spa one -m non-zero
示例2
題目描述
Given an array A with length n a[1],a[2],...,a[n] where a[i] (1<=i<=n) is positive integer. Count the number of pair (l,r) such that a[l],a[l+1],...,a[r] can be rearranged to form a geometric sequence. Geometric sequence is an array where each term after the first is found by multiplying the previous one by a fixed, non-zero number called the common ratio. i.e. A = [1,2,4,8,16] is a geometric sequence.輸入描述:
The first line is an integer n (1 <= n <= 100000).
The second line consists of n integer a[1],a[2],...,a[n] where a[i] <= 100000 for 1<=i<=n.
輸出描述:
An integer answer for the problem.示例1
輸入
5 1 1 2 4 1
輸出
11
說明
The 11 pairs of (l,r) are (1,1),(1,2),(2,2),(2,3),(2,4),(3,3),(3,4),(3,5),(4,4),(4,5),(5,5).
輸入
10 3 1 1 1 5 2 2 5 3 3
輸出
20
備註:
The answer can be quite large that you may use long long in C++ or the similar in other languages.
題解
暴力。
先統計公比為$1$的區間有幾種,接下來,無論公比為多少,區間長度不會超過$17$,因此只要枚舉區間起點,驗證$17$個區間即可。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100000 + 10; int n; long long a[maxn]; long long b[maxn]; int sz; int check() { if(b[0] == b[sz - 1]) return 0; if(sz == 2) return 1; for(int i = 2; i < sz; i ++) { if(b[1] * b[i - 1] != b[0] * b[i]) return 0; } return 1; } int main() { while(~scanf("%d", &n)) { for(int i = 1; i <= n; i ++) { scanf("%lld", &a[i]); } long long ans = 1; long long sum = 1; for(int i = 2; i <= n; i ++) { if(a[i] == a[i - 1]) sum ++; else sum = 1; ans = ans + sum; } for(int i = 1; i <= n; i ++) { sz = 0; for(int j = i; j <= min(n, i + 20); j ++) { b[sz ++] = a[j]; int p = sz - 1; while(p && b[p] < b[p - 1]) { swap(b[p], b[p - 1]); p --; } ans = ans + check(); } } printf("%lld\n", ans); } return 0; }
湖南大學ACM程序設計新生杯大賽(同步賽)A - Array