因为对树的知识尚不熟悉, 所以只完成了A与B题。
A.凑数

这道题算是比较简单的, 通过输入的n去计算最大等差数列和最小等差数列, 如果所求数在这两个值之间, 则必然可求
#include <stdio.h>
_Bool Sum(unsigned long long n,unsigned long long k,unsigned long long s);
int main(void)
{
long t;
unsigned long long n, k, s;
scanf("%ld", &t);
for (long i = 0; i < t; i++)
{
scanf("%llu %llu %llu", &n, &k, &s);
if (Sum(n, k, s))
puts("Yes");
else
puts("No");
}
return 0;
}
_Bool Sum(unsigned long long n,unsigned long long k,unsigned long long s)
{
unsigned long long minSum = 0;
unsigned long long maxSum = 0;
minSum = (k * k + k)/ 2;
if (minSum > s)
return 0;
maxSum = (n + n - k + 1) * k / 2;
if (minSum <= s && maxSum >= s)
return 1;
else
return 0;
}
B. clear up





通过建立一个栈来不断存入弹出,
分三种情况
- 新入栈的被之前的盖住, 那就拒绝其入栈, continue
- 新入栈的可以盖住前面的, 那就不弹出上一个元素, 直到有一个不会被盖住
- 两个有区间交, 进行合并
- 两个无区间交, 入栈
三人组总有第四个人, 不是么
#include <stdio.h>
#define N 1000000
long long stack[N][3] = { 0 };
long long Marge(long long* restrict num, const long long n);
int main(void)
{
long long int retnum;
long long n;
long long num[N];
scanf("%lld", &n);
for (long long i = 0; i < n; i++)
scanf("%lld", &num[i]);
retnum = Marge(num, n);
printf("%lld", retnum);
return 0;
}
long long Marge(long long* restrict num, const long long n)
{
long long val;
long long stackPoint = 0;
long long i;
for (i = 0; i < n; i++)
{
if (num[i] == 0)
continue;
if (stackPoint > 0 && stack[stackPoint - 1][1] >= i + num[i])
continue;
stack[stackPoint][0] = i - num[i];
stack[stackPoint][1] = i + num[i];
stack[stackPoint][2] = num[i];
while (stackPoint > 0 && stack[stackPoint][0] <= stack[stackPoint - 1][0])
{
stack[stackPoint - 1][0] = stack[stackPoint][0];
stack[stackPoint - 1][1] = stack[stackPoint][1];
stack[stackPoint - 1][2] = stack[stackPoint][2];
stackPoint--;
}
while (stackPoint > 0 && stack[stackPoint - 1][1] >= stack[stackPoint][0])
{
long long temp = stack[stackPoint][1] - stack[stackPoint - 1][0];
temp += temp & 1 ? 1 : 0;
// printf("%lld\n", temp);
stack[stackPoint - 1][2] = temp / 2;
stack[stackPoint - 1][1] = stack[stackPoint][1];
stackPoint--;
}
stackPoint++;
}
for (i = 0, val = 0; i < stackPoint; i++)
{
// printf("%lld %lld %lld\n", stack[i][0], stack[i][1], stack[i][2]);
val += stack[i][2];
}
return val;
}
本文主要介绍了两个算法问题的解决方案。第一个问题是关于寻找特定数值是否存在于一个给定长度的最大和最小等差数列之间。第二个问题涉及使用栈来处理区间覆盖,通过判断新区间是否能合并到已有的区间栈中,实现有效的区间合并和计算。这两个问题都涉及到基础的数据结构和算法应用。

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



