每隔n步循环删除,返回最后一个元素
题目:有一个数组a[N]顺序存放0~N-1,要求每隔两个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置。以8个数(N=7)为例:{0,1,2,3,4,5,6,7},0->1->2(删除)->3->4->5(删除)->6->7->0(删除),如此循环直到最后一个数被删除。
题解一: 暴力解法,模拟,一步一步来。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 int n; // 长度 6 while(cin>>n){ 7 if(n>1000){ 8 n=1000; 9 } 10 vector<int> v(n); 11 for(int i=0;i<n;i++){ 12 v[i]=i; 13 } 14 vector<bool> v_b(n,false); 15 16 if(n==1){ 17 return v[0]; 18 } 19 20 int count=0; // 删除的count 21 int idx=-1; 22 while(count!=n-1){ 23 int step=0; 24 while(step<3){ 25 idx=(idx+1)%n; 26 if(v_b[idx]==false){ 27 step++; 28 } 29 } 30 v_b[idx]=true; 31 count++; 32 } 33 for(;v_b[idx]==true;idx=(idx+1)%n){ 34 ; 35 } 36 cout<<v[idx]<<endl; 37 } 38 return 0; 39 40 }
题解二:运用队列的思想进行循环插入和删除。
1 #include<queue> 2 using namespace std; 3 int main() 4 { 5 int n; 6 while(cin>>n) 7 { 8 queue<int> q; 9 for(int i=0;i<n;i++) 10 { 11 q.push(i); 12 } 13 int count=0; 14 while(q.size()!=1) 15 { 16 if(count!=2) 17 { 18 int b=q.front(); 19 q.pop(); 20 q.push(b); 21 count++; 22 } 23 else 24 { 25 q.pop(); 26 count=0; 27 } 28 } 29 int c=q.front(); 30 cout<<c<<endl; 31 } 32 return 0; 33 }
题解三: 约瑟夫环问题(以后再看)
1 //递推公式:f[1] = 0 ,f[n] = (f[n - 1] + K) mod n //如果想了解:http://blog.csdn.net/taoyanqi8932/article/details/52335719 2 #include <iostream> 3 using namespace std; 4 int lastNum(int n) { 5 int res=0; 6 for (int i=2;i<=n;i++) 7 res=(res+3)%i; 8 return res; 9 } 10 int main() { 11 int n; 12 while (cin>>n) 13 cout<<lastNum(n)<<endl; 14 }