`

zoj 1088 System Overload

 
阅读更多

  约瑟夫环 (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;
}
	
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics