Codeforces Round #722(Div. 2)B

B.Sifid and Strange Subsequences

原题链接


题目大意:
找出一个序列的子序列,满足子序列中任意两个元素之差的绝对值大于子序列最大值,求最大子序列长度

输入格式:
第一行包含整数T(1≤t≤1e4)–测试用例数。
测试用例的描述如下。
每个测试用例的第一行包含一个整数n(1≤n≤1e5)–数组A的长度。每个测试用例的第二行包含n整数a1,a2,…。,a2,…,(−1e9≤ai≤1e9)-数组A的元素。保证所有测试用例的n之和不超过1e5。

输出格式:
对于每个测试用例输出一个整数,表示满足条件的最大子序列长度

input
6
4
-1 -2 0 0
7
-3 4 -2 0 -4 6 1
5
0 5 -3 2 -5
3
2 3 1
4
-3 0 2 0
6
-3 -2 -1 1 1 1

output
4
5
4
1
3
4


思维题(codeforces里的题思维都强QWQ
想到了的话代码就会特别好写

满足条件的子序列一定包含所有非正数正数只能选择满足条件的一个

为什么呢?

首先因为要满足任意两个数的绝对值大于最大值,注意了,是绝对值!绝对值一定大于等于0,所以所有非负
正数一定会在最大满足条件的子序列中

当出现多个正数时,两个正数相减的绝对值肯定会小于其中大的正数,无论如何都会出现两个数绝对值小于最大值的情况,所以正数只能取一个,且必须满足条件

AC代码如下:

#include
#define ll long long 
using namespace std;
const int maxn=1e5+3;
int a[maxn];
int main(){
     
	int T;
	scanf("%d",&T);
	while(T--){
     
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;++i)
			scanf("%d",&a[i]);
		sort(a+1,a+n+1);
		int ans=0;
		int minn=1e9+1;
		for(int i=1;i<=n;++i){
     
			if(a[i]<=0)ans++;
			if(i!=1)minn=min(minn,abs(a[i]-a[i-1]));
			//因为i从1开始,注意特判i!=1,防止出问题
			if(a[i]>0&&minn>=a[i]){
     
				ans++;
				break;//只能取一个正数
			}
		}
		printf("%d\n",ans);
	}
	return 0;
} 

你可能感兴趣的:(题解)