题目一:P9532 [YsOI2023] 前缀和
题目描述
立秋有一个长度为 n 的数组 a,所有数字都是正整数,并且除了其中第一个数字以外其它数字都等于前面所有数字的和。
例如,数组 [1,1,2,4,8,16][1,1,2,4,8,16] 就有可能是立秋有的一个数组,因为除了第一个数字 11,后面的每个数字都是前面数字的和,例如:
- 第二个数字 1=11=1。
- 第三个数字 2=1+12=1+1。
- 第四个数字 4=1+1+24=1+1+2。
- 第五个数字 8=1+1+2+48=1+1+2+4。
- 第六个数字 16=1+1+2+4+816=1+1+2+4+8。
现在立秋告诉了秋丽数字 x 存在于这个数组中,秋丽希望知道 an 最小会是多少,或者说整个数组最后一个数字最小有多少。
输入格式
本题有多组测试数据。
输入第一行一个数字 T 表示测试数据组数。
接下来 T 行每行两个正整数 n,x。
输出格式
输出共 T 行,分别表示每组测试数据的答案。
对于某组数据 n,x,输出一行一个正整数表示可能的最小的 an
思路
首先使用 scanf
函数来读取测试数据的行数T。然后我们定义一个数组 a 来存储然后使用 scanf
函数来读取数组的长度 n 和数字 x。然后使用一个循环来判断 W是否能被 a[n-2] 整除。如果可以整除,则输出 W,并结束循环。如果不能整除,则将 W 值乘以 2。
题解
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
long long a[100];
long long sum = 1;
for (int i = 0; i <100; i++) {
a[i] = sum;
sum *= 2;
}
while (T--) {
int n, x;
scanf("%d %d", &n, &x);
long long W = x;
while (1) {
if (W % a[n - 2] == 0) {
printf("%lld\n", W);
break;
} else {
W *= 2;
}
}
}
return 0;
}
题目二:P1115 最大子段和
题目描述
给出一个长度为 n 的序列 a,选出其中连续且非空的一段使得这段和最大。
输入格式
第一行是一个整数,表示序列的长度 n。
第二行有 n 个整数,第 i 个整数表示序列的第 i 个数字a[i] 。
输出格式
输出一行一个整数表示答案。
思路
用 scanf
函数来读取序列的长度 n。定义一个数组 a 来存储序列中的元素,并使用循环来读取序列的每个元素的值。定义两个变量 sum1
和 sum2
,分别表示当前找到的最大子段和以及当前正在遍历的子段和。如果当前的子段和 sum
2大于 0,则将其加上当前元素的值。否则,就将当前子段和sum
2的值设置为当前元素的值。然后,比较当前子段和 sum2
和已经找到的最大子段和 sum1
的值,大的为结果。
题解
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int a[n];
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
int sum1 = a[0], sum2 = a[0];
for (int i = 1; i < n; i++) {
if (sum2 > 0) {
sum2 += a[i];
} else {
sum2 = a[i];
}
if (sum2 > sum1) {
sum1 = sum2;
}
}
printf("%d\n", sum1);
return 0;
}