codves1282 约瑟夫问题 链表 会 T

codves1282 约瑟夫问题

STL LIST 链表 暴力模拟 但是会 T list

听说正解是线段树
分析一下,我们有以下两种操作:

1. 找到剩余队列中第K个人在数组中的位置
2. 删除第K个人
假如我们一开始给每个人一个权值1,然后维护一个前缀和s(n)那么,操作1就变成了找到前缀和为i的位置。当将第i个人删除时,只需将其权值置0,维护好前缀和,这样剩余队列中第i’个人的实际位置就在原先第i人后面了。

我们可以把前缀和转换为区间和,所以我们可以用线段树进行快速操作

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iomanip>
 8 #include <iostream> 
 9 #include <list>
10 using namespace std ; 
11 
12 int n,k ; 
13 list<int> a ; 
14 list<int> ::iterator it ; 
15 list<int> ::iterator temp ; 
16 
17 int main() 
18 {
19     scanf("%d%d",&n,&k) ; 
20     for(int i=1;i<=n;i++) 
21         a.push_back( i ) ; 
22     it = a.begin() ;
23     for(int i=1;i<=n;i++) 
24     {
25         for(int j=1;j<k;j++) 
26             if( ++it==a.end() ) 
27                 it = a.begin() ;  
28         temp = it ; 
29         printf("%d ",*it ) ; 
30         if( ++it==a.end() )  
31             it = a.begin() ; 
32         a.erase(temp) ; 
33     } 
34     return 0 ; 
35 }

 

posted @ 2017-06-06 16:18  third2333  阅读(124)  评论(0编辑  收藏  举报