约瑟夫问题,程序死住了
- C/C++ code
#include<list>struct Jo{ int pos; bool flag; Jo(int nPos, bool bFlag):pos(nPos),flag(bFlag){}};class ResolveJo{ list<Jo> mylist; int step; int count;private: bool Check( int& nPos) const { list<Jo>::const_iterator iter=mylist.begin(); int n=0; while(iter!= mylist.end()) { if(iter->flag) n++; if(n==count-1) { nPos=iter->pos; return true; } return false; } }public: ResolveJo(int nCount,int nStep) { count=nCount; step=nStep; for(int i=0; i<count ;i++) mylist.push_back(Jo(i,true)); } void Solution() { list<Jo>::iterator iter=mylist.begin(); int m=0; int targetPos; do { if(Check(targetPos)) //只剩下一人 { cout<<targetPos<<endl; break; } //continue if(iter->flag) m++; if(m==step) { iter->flag=false; } } while (1); }};int main(){ ResolveJo obj(12,3); obj.Solution(); return 0;}
list一般是循环链表,所以可以用来解决约瑟夫问题,为什么程序死了。
问题2:
- C/C++ code
*iter.flag 这样使用为什么是错误的,*iter返回的是 list中存放的类型。既然是存放数据,就可以使用.了,但是编译无法通过??
[解决办法]
更正下上面的程序。刚才没有检查,发现有错误。替换这个函数就可以了
- C/C++ code
bool Check( int& nPos) const { list<Jo>::const_iterator iter=mylist.begin(); int n=0; while(iter!= mylist.end()) { if(!iter->flag) { n++; } else { nPos = iter->pos; } iter++; } if(n==count-1) { return true; } return false; }
[解决办法]
- C/C++ code
//假设有n个人团团围做,从第1个人开始数数,数到第m个人时候,第m个人出列,//然后继续从1开始数数,数到第m个人退出#include <stdio.h>#include <conio.h>int i,k,t;int n,m;static char f[1001];//0该座位未出圈,1该座位已出圈void main() { while (1) { printf("Input n m(1000>=n>=m>=1):"); fflush(stdout); rewind(stdin); if (2==scanf("%d%d",&n,&m)) { if (1000>=n && n>=m && m>=1) break; } } t=0;//已出圈总人数 i=1;//座位编号 k=1;//当前要数的数 while (1) { if (0==f[i]) { if (m==k) { t++; f[i]=1; printf("%3d ",i); if (0==t%10) printf("\n"); if (t>=n) break; } k++;if (k>m) k=1; } i++;if (i>n) i=1; } cprintf("Press any key ..."); getch();}
[解决办法]
实际上自己写个类似STL的环形类也不难,上个月我曾经写了一个,用来编写约瑟夫环简单得很。
只是一直没时间去完善它,也没时间去改成模板。
用尚未完成的环形类写的21人约瑟夫环:
- C/C++ code
#include "ring.h"#include <iostream>int main(){ ring r; for (int i=1;i<=21;++i) r.push_back(i); ring::iterator iter=r.begin(); do { for (int i=1;i<=4;++i) ++iter; iter=r.erase(iter); }while(r.Size()>1); std::cout<<"最后留下来的是:"<<*(r.begin())<<" 号";}