约瑟夫环 (josephus problem )问题,有公式 可以直接套用
我使用暴力破解方法求解(用时3秒多)。
代码如下:
/* zoj 1088 System Overload */
#include <stdio.h>
#include <string.h>
#define MAXBUILDING 150
int minStepNum(int totalBuilding, int lastNum);
int main(void)
{
int n;
/* int minStepTab[MAXBUILDING];
int i;
for(i = 3; i < MAXBUILDING; i++)
minStepTab[i] = minStepNum(i,2);*/
while(scanf("%d", &n) == 1 && n != 0)
/* printf("%d\n", minStepTab[n]);*/
printf("%d\n",minStepNum(n,2));
return 0;
}
int minStepNum(int totalBuilding, int lastNum)
{
int minStep = 2;
int count,i,flag;
int isCutOff[MAXBUILDING];
int buildings[MAXBUILDING];
for(i = 0; i < totalBuilding; i++)
buildings[i] = i+1;
while(1)
{
memset(isCutOff,0,sizeof(isCutOff));
isCutOff[0] = 1;
flag = 0;
for(i = count = 0; count < minStep * (totalBuilding-2);
i = (i+1)%totalBuilding)
if(isCutOff[i] == 0)
{
count++;
if(count % minStep == 0 && buildings[i] == lastNum)
{
flag = 1;
break;
}
else if(count % minStep == 0)
isCutOff[i] = 1;
}
if(count == minStep*(totalBuilding-2) && !flag)
for(i = 0; i < totalBuilding; i++)
if(isCutOff[i] == 0)
return minStep;
minStep++;
}
return 0;
}
直接套用公式的代码(15ms):
#include <stdio.h>
int Josephus(int n, int m)
{
if(n == 1)
return 0;
else
return (Josephus(n-1,m)+m)%n;
}
int main(void)
{
int n;
int i;
while(scanf("%d", &n) == 1 && n != 0)
{
for(i = 2;; i++)
if(Josephus(n-1,i) == 0)
{
printf("%d\n",i);
break;
}
}
return 0;
}
起初我使用最原始的暴力破解法(未使用任何优化),结果超时了(可能需要15秒左右,超出了规定的10秒限制)
产生超时结果对应代码:
/* zoj 1088 System Overload */
#include <stdio.h>
#include <string.h>
#define MAXBUILDING 150
int lastNumber(int totalBuilding, int stepNum);
int minStepNum(int totalBuilding, int lastNum);
int main(void)
{
int n;
int minStepTab[MAXBUILDING];
int i;
for(i = 3; i < MAXBUILDING; i++)
minStepTab[i] = minStepNum(i,2);
while(scanf("%d", &n) == 1 && n != 0)
printf("%d\n", minStepTab[n]);
/* printf("%d\n",minStepNum(n,2));*/
return 0;
}
int minStepNum(int totalBuilding, int lastNum)
{
int i;
for(i = 2; lastNumber(totalBuilding,i) != lastNum; i++) ;
return i;
}
int lastNumber(int totalBuilding, int stepNum)
{
int building[MAXBUILDING],isCutOff[MAXBUILDING];
int i,count;
memset(isCutOff,0,sizeof(isCutOff));
for(i = 0; i < totalBuilding; i++)
building[i] = i+1;
isCutOff[i=0] = 1;
/* count = 0;*/
for(count = 0;count < stepNum * (totalBuilding-2); i = (i+1)%totalBuilding)
if(isCutOff[i] == 0)
{
count++;
if(count % stepNum == 0)
isCutOff[i] = 1;
}
for(i = 0; i < totalBuilding; i++)
if(isCutOff[i] == 0)
return building[i];
return 0;
}
本文探讨了约瑟夫环问题的多种解决方法,包括暴力破解、直接套用公式以及优化后的代码实现。重点对比了不同方法的时间效率,并通过代码实例展示了如何有效减少计算复杂度。
2109

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



