【发布时间】:2013-09-24 14:32:06
【问题描述】:
我遇到了算法复杂性的问题,我尝试了下面的解决方案,认为当我忘记考虑时间限制时这很容易。我在下面添加了我的代码,我什至不确定它的复杂性。我很想知道O(N) 或O(K) 解决方案是什么。如果有人能帮忙解决这个问题,将不胜感激。
Time Limit: 1 second
有 K 个座位可用,每个座位都由一个物理座位表示,位于一个圆圈周围。 K+1 人最初也站在圆圈周围的点上。圆上的点从 1 到 N 顺时针标记,这样点 1 紧跟在 N 点之后。最初不会有两个人站在同一点,也不会有两把椅子在同一点。
每一秒,所有仍然站立的人(同时)执行以下操作:
如果此人与空椅子站在同一位置,则此人将坐在其中。
否则,此人将围绕圆圈顺时针移动一个位置到下一个点。如果此人之前位于点 i(i
由于有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]);
【问题讨论】:
-
提示:人和椅子的确切位置并不重要。一个人最终坐的椅子仅取决于人和椅子的顺序。你能看出为什么吗? (免责声明:确保这是真的,因为我目前睡眠不足。)
-
@user2357112 我有点想类似的东西,但不知道他们最终会坐在哪把椅子上
-
解决这个问题的一种方法是意识到如果没有人站在一个人和下一张空椅子之间,那个人会坐在那把椅子上,你可以把这个人和椅子从问题。
标签: c++ python performance algorithm simulation