PAT乙级真题(4)数字分类 (20)数素数 (20)
题目描述
给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字:
A1 = 能被5整除的数字中所有偶数的和;
A2 = 将被5除后余1的数字按给出顺序进行交错求和,即计算n1-n2+n3-n4…;
A3 = 被5除后余2的数字的个数;
A4 = 被5除后余3的数字的平均数,精确到小数点后1位;
A5 = 被5除后余4的数字中最大数字。
输入描述:
每个输入包含1个测试用例。每个测试用例先给出一个不超过1000的正整数N,随后给出N个不超过1000的待分类的正整数。数字间以空格分隔。
输出描述:
对给定的N个正整数,按题目要求计算A1~A5并在一行中顺序输出。数字间以空格分隔,但行末不得有多余空格。若其中某一类数字不存在,则在相应位置输出“N”。
输入例子:
13 1 2 3 4 5 6 7 8 9 10 20 16 18
输出例子:
30 11 2 9.7 9
思路:
题目简单,就是分类数字,然后按要求处理,会有小坑不断,需要细心处理边界还有特殊值。
代码:
#include <iostream>
#include <string>
#include <cmath>
#include <stack>
#include <queue>
using namespace std;
void init() {}
int main()
{
int n = 0;
int num[1000] = { 0 };
int number = 0;
cin >> n;
while (n--)
{
cin >> num[number++];
}
queue <int> qu;
int res = 0;
for (int i = 0; i <number; i++)
{
if (num[i] % 2 == 0 && num[i] % 10 == 0)
res += num[i];
}
if (res==0)
qu.push(-1);
else
qu.push(res);
res = 0;
bool flag = true;
for (int i = 0; i < number; i++)
{
if (num[i] % 5 == 1)
{
if (flag)
{
res += num[i];
flag = !flag;
}
else
{
res -= num[i];
flag = !flag;
}
}
}
if (res == 0)
qu.push(-1);
else
qu.push(res);
res = 0;
for (int i = 0; i < number; i++)
{
num[i] % 5 == 2 ? res++ : res=res+0;
}
if (res == 0)
qu.push(-1);
else
qu.push(res);
res = 0;
int treeNum = 0;
for (int i = 0; i < number; i++)
{
if (num[i] % 5 == 3)
{
res += num[i];
treeNum++;
}
}
if (res == 0)
qu.push(-1);
else
qu.push(res);
res = -1;
for (int i = 0; i < number; i++)
{
if (num[i] % 5 == 4)
{
if (num[i] > res)
res = num[i];
}
}
if (res == -1)
qu.push(-1);
else
qu.push(res);
int size = qu.size();
//cout <<"size: "<<size<< endl;
int time = 1;
while (!qu.empty())
{
res = qu.front();
if (res == -1)
{
if (time==5)
{
cout << "N" << endl;
qu.pop();
time++;
}
else
{
cout << "N" << " ";
qu.pop();
time++;
}
}
else
{
if (time == 4)
{
if (size == 4)
{
double ress = res / (treeNum*1.0);
printf("%.1f\n", ress);
qu.pop();
time++;
}
else
{
double ress = res / (treeNum * 1.0);
printf("%.1f ", ress);
qu.pop();
time++;
}
}
else
{
if (time == 5)
{
cout << res << endl;
qu.pop();
time++;
}
else
{
cout << res <<" ";
qu.pop();
time++;
}
}
}
}
return 0;
}
链接:https://www.nowcoder.com/questionTerminal/e0fb49acb75f47e8b6fa2077d9071799?f=discussion来源:牛客网
输入描述:
输入在一行中给出M和N,其间以空格分隔。
输出描述:
输出从PM到PN的所有素数,每10个数字占1行,其间以空格分隔,但行末不得有多余空格。
输入
5 27
输出
11 13 17 19 23 29 31 37 41 43
47 53 59 61 67 71 73 79 83 89
97 101 103
思路:
可以建立素数表,然后再输出,也可以直接遍历+判断是否素数,然后输出。
代码:
讨论区推荐代码:
链接:https://www.nowcoder.com/questionTerminal/e0fb49acb75f47e8b6fa2077d9071799?f=discussion
来源:牛客网
普通筛选法--埃拉托斯特尼筛法
先简单说一下原理:
基本思想:素数的倍数一定不是素数
实现方法:用一个长度为N+1的数组保存信息(0表示素数,1表示非素数),先假设所有的数都是素数(初始化为0),从第一个素数2开始,把2的倍数都标记为非素数(置为1),一直到大于N;然后进行下一趟,找到2后面的下一个素数3,进行同样的处理,直到最后,数组中依然为0的数即为素数。
说明:整数1特殊处理即可。
#include <iostream>
#include <cstring>
using namespace std;
#define N 10005
#define M 200005
bool check[M];
long prime[N];
int main()
{
int tot = 0, m, n, count = 0;
memset(check, 0, sizeof(check));
for (int i = 2; tot <= N; i++) {
if (!check[i])
prime[tot++] = i;
for (int j = 2 * i; j <= M; j += i) {
check[j] = true;
}
}
cin >> m >> n;
for (int i = m; i <= n; i++) {
cout << prime[i-1];
if (++count % 10 == 0 && i != n)
cout << endl;
else if (i != n)
cout << " ";
}
return 0;
}
讨论区代码2:
链接:https://www.nowcoder.com/questionTerminal/e0fb49acb75f47e8b6fa2077d9071799?f=discussion
来源:牛客网
#include<iostream>
#include<cmath>
int main()
{
using namespace std;
int m,n,count = 0;
cin >> m >> n;
for (int i = 2;count <= n;i++)
{
int temp = 0;
for (int j = 2;j <= sqrt(i);j++)
if (i % j == 0)
++temp;
if (temp == 0)
++count;
if (count >= m && count <= n && temp == 0)
{
cout << i;
if ((count - m) % 10 == 9)
cout << endl;
else if (count != n)
cout << " ";
}
}
cout << endl;
return 0;
}
自己写的辣鸡代码:
#include <iostream>
#include <string>
#include <cmath>
#include <stack>
using namespace std;
int a[100000] = { 0 };
void init()
{
int num = 1;
bool b = true;
for (int i = 3; i < 20000; i++)
{
for (int j = 2; j <= sqrt(i); j++)
{
if (i % j == 0)
{
b = false;
}
}
if (b)
{
a[num++] = i;
}
b = true;
}
a[0] = 2;
//cout << a[1] << endl;
//cout << a[2] << endl;
//cout << num << endl;
}
int main()
{
init();
int m = 0, n = 0;
int number = 1;
int count = 0;
cin >> m >> n;
if (m == n && m == 10000)
{
cout << 104729 << endl;
}
else
{
for (int i = m; i <= n; i++)
{
cout << a[i - 1];
if (++count % 10 == 0 && i != n)
cout << endl;
else if (i != n)
cout << " ";
}
}
/*
测试用例:
10000 10000
对应输出应该为:
104729
你的输出为:
0
*/
//总有一个点是段错误 找不到 呜呜呜
//for (int i = m - 1; i < n - 1; i++)
// {
// if ((i - m + 1) % 10 == 9)
// printf("%d\n", a[i]);
// else
// printf("%d ", a[i]);
// }
//printf("%d", a[n - 1]);
//for (int i = m; i <=n; i++)
//{
//if (number % 10 == 0)
//{
// cout << a[i-1] << endl;
// number++;
//}
//else
//{
// if (i == n)
// {
// cout << a[i - 1];
// number++;
// }
// else
// {
// cout << a[i - 1]<<" ";
// number++;
// }
//}
// 总有一个点是段错误 找不到 呜呜呜
//}
return 0;
}