「BZOJ1385」「Baltic2000」Division expression 解题报告

Division expression

Description

除法表达式有如下的形式: (X_1/X_2/X_3.../X_k) 其中Xi是正整数且(X_i le 1000000000(1 le i le k,K le 10000)) 除法表达式应当按照从左到右的顺序求,例如表达式1/2/1/2的值为1/4.但可以在表达式中加入括号来改变计算顺序,例如(1/2)/(1/2)的值为1.现给出一个除法表达式E,求是告诉是否可以通过增加括号来使其为E',E'为整数。

Input

先给出一个数字D,代表有D组数据. 每组数据先给出一个数字N,代表这组数据将有N个数。 接下来有N个数

Output

如果能使得表达式的值为一个整数,则输出YES.否则为NO

Sample Input

2
4
1
2
1
2
3
1
2
3

Sample Output

YES
NO

思路

观察这个式子(E = X_1 / X_2 / X_3 .... / X_n)

我们设(E' = X_{a1} * X_{a2}..../ X_{b1} / X_{b2}....)

即把加括号后的式子改成分数线的形式,有一些元素属于分子,其他的元素属于分母。

我们发现:

  • (X_1) 不得不在分子 没有为什么 就是不可以
  • (X_2) 不得不在分母 因为你想让它去分母它也不可能到分母
  • (X_3 to X_n) 可在分子也可在分母 总是有办法的QAQ

如果叫你把(X_3 to X_n)分一部分在分子,其他的在分母,你会怎么做?? 当然是把全部元素放在分子呗。。。

因此最优的 (E' = X_1 * X_3 * X_4....* X_n / X_2)

如果真的乘起来的话肯定会溢出,所以当然要用GCD。

清爽的30行代码$(~ ̄▽ ̄)~ $

代码

#include<cstdio>
using namespace std;
#define MAXN 10005

int T;
int n, t, s;

int gcd( int x, int y ){
    return x % y == 0 ? y : gcd( y, x % y );
}

int main(){
    scanf( "%d", &T );
    while( T-- ){
        scanf( "%d", &n );
        scanf( "%d", &t );
        if ( n == 1 ){//注意特判
            printf( "YES
" ); continue;
        }
        scanf( "%d", &s );
        s /= gcd( s, t );
        for ( int i = 3; i <= n; ++i ){
            scanf( "%d", &t );
            s /= gcd( s, t );
        }
        if ( s == 1 ) printf( "YES
" );
        else printf( "NO
" );
    }
    return 0;
}
原文地址:https://www.cnblogs.com/louhancheng/p/10060719.html