P1996 约瑟夫问题-题解(队列??明明是单循环链好吗)
一如既往的题目传送: https://www.luogu.org/problemnew/show/P1996
这里不讲数组模拟的方法(毕竟多做点题的模拟功力足以暴力出这道题),而是讲一种单循环链的做法。
读一下题就能发现题目中线性循环的思想,且题目数据范围不大,便考虑用单循环链模拟计数:
我们用数组来模拟这一链形结构:a[i]存放编号为i的节点的下一个节点的编号,(在本题中初始为a[1]=2,a[2]=3,...,a[n-1]=n,a[n]=1)这样每个节点都被上一个节点联系起来,所有节点就被“串成了一个循环链”,设j为指向当前报数节点的节点,当前报数节点即为a[j],当报数=m时,说明报数节点要离场,这是可让指着它的节点不再指它,而是指向它指向的节点,这样当前的报数节点就被整体的链给“驱逐”了。直到链的长度为0时,程序结束。
附AC代码:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int a[101],n,m; 5 int main() 6 { 7 cin>>n>>m; 8 for(int i=1;i<n;i++) 9 a[i]=i+1; 10 a[n]=1; 11 int j=n,p=0,k=1;//k为当前报数,p为离场(出圈)人数 12 while(p<n) 13 { 14 while(k<m) 15 { 16 j=a[j]; 17 k++; 18 } 19 printf("%d ",a[j]); 20 a[j]=a[a[j]]; 21 k=1; 22 p++; 23 } 24 return 0; 25 }