1. 程式人生 > >湖南大學ACM程序設計新生杯大賽(同步賽)A - Array

湖南大學ACM程序設計新生杯大賽(同步賽)A - Array

ons arr algo mes 暴力 spa one -m non-zero

題目描述

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).
示例2

輸入

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