HDU 6917 Shorten the array

题目链接

Problem Description

Alice has an array a. The array has N positive numbers. She thinks the array is too long, so she wants to shorten the array. She decides to shorten the array via the following operation: every time she will choose an index i ( 1 ≤ i < n ) i (1≤i<n) i(1i<n) which a i > 0 ai>0 ai>0 and a i + 1 > 0 a_i+1>0 ai+1>0. She will delete a i a_i ai and a i + 1 a_i+1 ai+1 and use ( a i (a_i (ai m o d mod mod a i + 1 ) ai+1) ai+1) or ( a i + 1 (ai+1 (ai+1 m o d mod mod a i ) a_i) ai) to replace them.

For example, for array [ 3 , 2 , 4 , 5 ] [3,2,4,5] [3,2,4,5], if Alice choose i = 2 i=2 i=2, she can change the array to [ 3 , 2 , 5 ] [3,2,5] [3,2,5] or [ 3 , 0 , 5 ] [3,0,5] [3,0,5]. Alice wants you to tell her the shortest possible length of the array after several options.

Input

The first line contains a single integer T ( 1 ≤ T ≤ 10 ) T (1≤T≤10) T(1T10), indicating the number of test cases.

For each test cases:

The first line contains one integer N ( 2 ≤ N ≤ 1 0 6 ) N (2≤N≤10^6) N(2N106), indicating the size of the array.

The next line contains N N N integers a i ( a i ≤ 1 0 9 ) a_i (a_i≤10^9) ai(ai109), representing the array.

Output

Output T T T lines.

The i − t h i-th ith line contains a single integer, representing the answer of i − t h i-th ith test case.

Sample Input

2
4
1 1 1 1
4
2 3 4 5

Sample Output

2
1

Hint

For the first sample, Alice first choose i = 1 i=1 i=1 to change the array to [ 0 , 1 , 1 ] [0, 1, 1] [0,1,1], then choose i = 2 i=2 i=2 to change the array to [ 0 , 0 ] [0, 0] [0,0], which is the best result she can reach.

解题思路:

取模运算有如下性质:
a % b = a    ( a < b ) a\%b=a \ \ (a<b) a%b=a  (a<b)
Case1:对于样例2: 2   3   4   5 2\ 3\ 4\ 5 2 3 4 5

我们可以用最小的数 2 2 2对其余数进行取模运算,即 2 % 3 , 2 % 4 , 2 % 5 2\%3,2\%4,2\%5 2%3,2%4,2%5,最后数组元素只剩2,长度为1。

Case2:题目要求做运算的数必须大于0。对于样例1: 1   1   1   1 1\ 1\ 1\ 1 1 1 1 1
得到最终结果为 0   0 0 \ 0 0 0,数组长度为2

可知,当数组中只存在相同的数时,数组长度为 i i i i + 1 i+1 i+1将得到同样的结果,都是 ( i + 1 ) / 2 (i+1)/2 (i+1)/2

Case3:对于样例 2   2   2   3   4   5 2\ 2\ 2\ 3\ 4\ 5 2 2 2 3 4 5
按如上做法将会得到答案为 2   ( 0   2 ) 2\ (0\ 2) 2 (0 2)。但若进行运算时可以得到比最小数(min=2)更小的数,如3%2=1,将此更小的数保存下来(而不是保存2%3=2),此时最小数将更新。于是如此处理后的数组将变为 2   2   1 2\ 2\ 1 2 2 1
最后可以将其他所有的数吞并,最终答案一定为1。

注意:第二次更新的最小数 x x x需满足 ( x > 0 & & x < m i n ) (x>0 \&\&x<min) (x>0&&x<min),并且只能转换一个更小的数来达到目标。

AC代码:

#include<iostream>
#define int long long
using namespace std;
int a[1000005];
int t,n;
signed main()
{
    // ATTENTION %LLD FOR LONG LONG !!!
    scanf("%lld",&t);
    while(t--)
    {
        int minn=1000000005;
        scanf("%lld",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%lld",&a[i]);
            if(minn>a[i])   minn=a[i];
        }
        int s=0,f=0;
        for(int i=0;i<n;i++)
        {
        	if((a[i]%minn>0&&a[i]%minn<minn))
        	//判断运算后是否能生成更小的数
        	//此处只需判断与minn的余数即可
        	{
        		f=1;
        		break;
			}
            if(minn==a[i])  s++;
        }
		if(f==1)	printf("1\n");
        else printf("%lld\n",(s+1)/2);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值