描述
题解
计算几何问题,这里的考点是三角形周长和边长的关系。
众所周知,三角形周长大于任意一条边的两倍,那么只要大于最长的一条边长,那么一定可以构成三角形。
接着,我们来分析在什么时候需要考虑是否可以三角形问题。
看到这个问题,步数是循环数组A的,所以,A数组循环情况可以分为以下三种:
1、不到一循环;
2、一循环开外,不到两循环;
3、两循环开外。
第一种,不到一循环,比如说x
步(x < N
),那么我们需要保证周长大于等于2 * MAXA[x - 1]
,大于是三角形,等于是两条重合的线段;
第二种,则需要保证周长大于等于2 * MAXA[N - 1]
;
第三种,我们可以知道,最长边MAXA[N - 1]
一定出现过两次及其以上,所以一定可以构成多边形,则不用过多判断。
那么,我们只需要进行第一种第二种的特别判断,判断时,可以将第一种第二种合并起来考虑,一定要注意构成两条重合线段的情况,细节问题。
复杂度为O(N)
。
代码
#include <iostream>
#include <cmath>
using namespace std;
const int MAXN = 55;
int A[MAXN];
int MAXA[MAXN];
long long sum[MAXN];
int main(int argc, const char * argv[])
{
// freopen("/Users/zyj/Desktop/input.txt", "r", stdin);
int T;
cin >> T;
while (T--)
{
int x, N;
cin >> x >> N;
for (int i = 0; i < N; i++)
{
scanf("%d", A + i);
if (i == 0)
{
sum[i] = A[i];
MAXA[i] = A[i];
continue;
}
sum[i] = sum[i - 1] + A[i];
MAXA[i] = MAXA[i - 1] > A[i] ? MAXA[i - 1] : A[i];
}
int len = abs(x);
int div = len / sum[N - 1];
len -= div * sum[N - 1];
if (len == 0)
{
cout << div * N << '\n';
continue;
}
for (int i = 0; i < N; i++)
{
if (sum[i] >= len)
{
int steps = div * N + i + 1;
if (div > 1)
{
cout << steps << '\n';
}
else
{
int MAXA_ = div > 0 ? MAXA[N - 1] : MAXA[i];
long long C = div * sum[N - 1] + sum[i] + abs(x);
if (C >= 2 * MAXA_)
{
cout << steps << '\n';
}
else
{
for (int j = 1; j <= 2 * N; j++)
{
MAXA_ = MAXA_ > MAXA[(i + j) % N] ? MAXA_ : MAXA[(i + j) % N];
C += A[(i + j) % N];
if (C >= 2 * MAXA_)
{
cout << steps + j << '\n';
break;
}
}
}
}
break;
}
}
}
return 0;
}