我遇到了算法复杂性的问题,我尝试了下面的解决方案,认为当我忘记考虑时间限制时这很容易。我在下面添加了我的代码,我什至不确定它的复杂性。我很想知道O(N)
orO(K)
解决方案是什么。如果有人可以帮助解决这个问题,将不胜感激。
Time Limit: 1 second
有 K 个座位可用,每个座位都由一个围绕圆圈的点的物理座位表示。K+1 人最初也站在圆圈周围的点上。圆上的点从 1 到 N 顺时针标记,这样点 1 紧跟在 N 点之后。最初不会有两个人站在同一点,也不会有两把椅子在同一点。
每一秒,所有仍然站立的人(同时)执行以下操作:
如果此人与空椅子站在同一位置,则此人将坐在其中。
否则,该人将围绕圆圈顺时针移动一个位置到下一个点。如果此人之前位于点 i(i < N),则此人现在将位于点 i+1。如果此人先前位于点 N,则此人现在将位于点 1。
由于有 K+1 人,最终所有 K 个座位都会被占用,剩下的一个人没有座位。坐在圈子里第一个座位的人将有最好的位置。(圆圈中的“第一个”座位定义为从点 1 顺时针方向的第一个座位。)
你的任务是确定谁将坐在第一个座位上,谁将是站起来的人。
输入 N 和 K。K
以空格分隔的整数,表示有椅子的点,按升序排列。因此,此列表中的第一把椅子将是第一个座位
K+1 空格分隔的整数,代表人们的积分,按升序排列。这些人按他们在此列表中的位置从 1 到 K+1 编号。
1 ≤ N ≤ 1000000
1 ≤ K ≤ 100000
输出
第一个座位上的
人留下站立 的人
Sample
Input
10 3
2 5 8
3 4 6 8
Output
3
1
在第一秒,第四个人(在第 8 点)将立即坐在他们下方的椅子上。其他三个人将围绕圆圈移动一位。下一秒,第二个人(现在在位置 5)将坐在第二个座位上。第一个人和第三个人继续绕圈走,直到第三个人到达位置 2 并坐下,第一个人没有椅子可以坐。
while(standing != 1)
{
for (int i = 0; i < K + 1; i++)
{
if (sitting[i] == 0)
{
people[i]++;
if (isSitting(people[i], chairs,i)) //this function checks if the current person is at a chair
{
sitting[i] = 1;
standing--;
}
if (people[i] > N)
{
people[i] = 1;
}
}
}
}
standingPerson = indexOf(sitting,K+1 ,0);
此尝试几乎在所有测试输入上都超时,仅通过了 8/30 个案例。
这是使用另一个用户建议的 O(k) 解决方案的一些代码。转移到 C++
int seat1 = chairs[0], best = -1, accum = 1;
int unlucky[] = {0, -1};
for (int pos; pos < K + 1; pos++) {
if (people[pos] <= seat1) {
best = people[pos] + 1;
accum -= 1;
} else
break;
}
if (accum < 0) {
unlucky[0] = accum;
unlucky[1] = 1;
}
int i = K, j = K - 1;
while (i >= 0 && people[i] > seat1) {
if (chairs[j] >= people[i]) {
accum += 1;
j -= 1;
} else {
accum -= 1;
i -= 1;
}
if (best == -1 && accum == 0) {
best = i + 2;
}
if (accum < unlucky[0]) {
unlucky[0] = accum;
unlucky[1] = i + 2;
}
}
fprintf(out_file, "%d\n%d", best, unlucky[1]);