zoj--1088--System Overload

这道题开始一看还真没有什么思路,后面看了一下数据范围,数据不大

就直接暴力枚举求解了,最后也过了。

后来在网上查了一下,有人讲这是一个关于约瑟夫环的问题,就去看了一下约瑟夫环的相关知识

才发现是原来是有公式的。。。。。。。。。。。


下面是关于约瑟夫环问题的一篇文章的链接

http://blog.csdn.net/sunandice/article/details/6560889


代码如下:

第一个是直接枚举求解,第二个是公式法

//直接枚举m求解
#include<iostream>
using namespace std;

int main()
{
    int a[155],n,i,b[155];
    while(cin>>n&&n)
    {
         for(i=0;i<n;i++)
         {
            a[i]=i+1;
            b[i]=a[i];
         }
         int m=1,sum,cnt,k;
         while(1)
         {
             int flag=0;
             sum=1; cnt=0; a[0]=0; k=1;
             while(1)
             {
                 if(a[k])
                   cnt++;
                 if(cnt==m)
                 {
                    a[k]=0;
                    sum++;
                    cnt=0;
                 }
                 k=(k+1)%n;  //循环队列思想
                 if(a[1]&&sum==n-1)
                 {
                    flag=1;
                    break;
                 }
                 if(!a[1]&&sum<=n-1)
                   break;
             }
             for(i=0;i<n;i++)//开始时没考虑到每一次模拟都会导致a[]变化
                 a[i]=b[i];  //所以总是陷入死循环;b[]的作用就是每枚举一次m后重新恢复a[]的值
             if(flag)
             {
               cout<<m<<endl;
               break;
             }
             m++;
        }
    }
  return 0;
}

//问题二:求出最后出圈的那个人的序号
//方法一:模拟,最后留下的元素就是所求元素
//方法二:利用递推公式 f[1]=0 f(i)=f(f[i-1]+m)%i; 
#include<iostream>
using namespace std;

int n,m;
bool judge()
{
    int from = 0;
    for(int i = 2 ;i < n ; i ++)
      from = (from + m)%i;
    if(from + 1 == 1) return true;//最后剩下的那栋楼的最开始的编号是1的话,返回true
    else return false;
}

int main()
{
     while(cin>>n&&n)
     {
         m=1;
         while(!judge())
              ++m;
         cout<<m<<endl;
     }
  return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值