题目大意:给你N个数字,要求求出由这N个数字组成的一个序列的最大长度是多少,序列的组成规则如下:正负数交替出现,相邻的两个数绝对值小的要放前面
解题思路:
1.按绝对值从小到大排序,然后再依次判断
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 500010
int num[maxn];
bool cmp(const int a, const int b) {
return abs(a) < abs(b);
}
int main() {
int test, n;
scanf("%d",&test);
while(test--) {
scanf("%d",&n);
for(int i = 0; i < n; i++)
scanf("%d",&num[i]);
sort(num,num+n,cmp);
int sign = (num[0] < 0 ? -1:1);
int ans = 1;
for(int i = 1; i < n; i++) {
if(sign * num[i] < 0) {
ans++;
sign = -sign;
}
}
printf("%d\n",ans);
}
return 0;
}
2.这个思路比较麻烦,就是分成两个数组,然后再一一比对
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 500010
int Z[maxn], F[maxn];
int main() {
int test;
scanf("%d",&test);
while(test--) {
int Negative = 0, Positive = 0, N, t;
scanf("%d",&N);
for(int i = 0; i < N; i++) {
scanf("%d",&t);
if(t < 0)
F[Negative++] = t;
else
Z[Positive++] = t;
}
//只有一种颜色
if(Negative == 0 || Positive == 0) {
printf("1\n");
continue;
}
sort(F,F+Negative);
sort(Z,Z+Positive);
//找到最小的那个数在哪个数组
int ans = 1;
int L = 0, R = Negative - 1, MIN, sign;
if(abs(F[R]) < Z[0]) {
sign = 1;
MIN = -F[R];
R--;
}
else {
L++;
sign = -1;
MIN = Z[0];
}
//进行判断,sign==1表示下一个要正数,
while(L < Positive && R >= 0) {
if(sign == 1) {
while( L < Positive && Z[L] < MIN) {
L++;
}
if(L < Positive) {
MIN = Z[L];
ans++;
sign = -1;
L++;
}
}
else {
while(R >= 0 && abs(F[R]) < MIN)
R--;
if(R >= 0) {
MIN = -F[R];
ans++;
sign = 1;
R--;
}
}
}
//样例可能某一种颜色只有一个数,且这个颜色是最小值,按照上面的做法的话,就活漏掉这种情况
if(L == Positive) {
if(sign == -1) {
while(R >= 0 && abs(F[R]) < MIN)
R--;
if(R >= 0)
ans++;
}
}
else if(R < 0) {
if(sign == 1) {
while(L < Positive && Z[L] < MIN)
L++;
if(L < Positive)
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}