题目描述
在一个给定的序列中,寻找一个最长的子序列(不要求连续),使得该子序列的和除以3的余数为0。
输入
从文件 seq.in 中读入数据。
第一行n,表示共有n个数。
第二行共n个数,用一个空格隔开。
输出
输出到文件 seq.out 中。
输出就一个整数,所求子序列的最大长度。
样例输入 复制
6 1 2 2 1 2 5
样例输出 复制
5
数据范围限制
存在子序列1 2 2 2 5符合条件
提示
对于20%的数据,n<=10
对于60%的数据,n<=1000
对于100%的数据,n<=100000,序列中的数<=100000。
思路:
这道题其实就是道数学题,除了输入,其他地方连循环都不用。
AC代码:
#include<bits/stdc++.h> // 包含常用头文件
using namespace std;
int n,s; // n:数字个数 s:所有数字总和
int a; // 临时变量,用于读取每个数字
int n1[10]; // 数组n1[0],n1[1],n1[2]分别记录余数为0,1,2的数字个数
int main()
{
freopen("seq.in","r",stdin); // 重定向输入到文件
freopen("seq.out","w",stdout); // 重定向输出到文件
scanf("%d",&n); // 读取数字个数n
for(int i=1;i<=n;i++) // 循环读取每个数字
{
scanf("%d",&a); // 读取当前数字
s+=a,n1[a%3]+=1; // 累加总和s,并统计余数分布
}
s%=3; // 计算总和除以3的余数
if(s==0) // 如果总和余0,直接取全部数字
{
printf("%d",n);
return 0;
}
else if(s==1) // 如果总和余1
{
if(n1[1]!=0) // 优先去掉1个余1的数字
{
printf("%d",n-1);
return 0;
}
else if(n1[2]>=2) // 如果没有余1的数字,去掉2个余2的数字
{
printf("%d",n-2);
return 0;
}
}
else if(s==2) // 如果总和余2
{
if(n1[2]!=0) // 优先去掉1个余2的数字
{
printf("%d",n-1);
return 0;
}
else if(n1[1]>=2) // 如果没有余2的数字,去掉2个余1的数字
{
printf("%d",n-2);
return 0;
}
}
printf("%d",n); // 如果无法调整,只能取全部数字
return 0;
}

被折叠的 条评论
为什么被折叠?



