HDU 5860 Death Sequence (递推 + 约瑟夫环 + 思维)——2016 Multi-University Training Contest 10
2016-08-20 20:13
531 查看
传送门
Total Submission(s): 379 Accepted Submission(s): 163
[align=left]Problem Description[/align] You may heard of the Joseph Problem, the story comes from a Jewish historian living in 1st century. He and his 40 comrade soldiers were trapped in a cave, the exit of which was blocked by Romans. They chose suicide over capture and decided that they would form a circle and start killing themselves using a step of three. Josephus states that by luck or maybe by the hand of God, he and another man remained the last and gave up to the Romans.
Now the problem is much easier: we have N men stand in a line and labeled from 1 to N, for each round, we choose the first man, the k+1-th one, the 2*k+1-th one and so on, until the end of the line. These poor guys will be kicked out of the line and we will execute them immediately (may be head chop, or just shoot them, whatever), and then we start the next round with the remaining guys. The little difference between the Romans and us is, in our version of story, NO ONE SURVIVES. Your goal is to find out the death sequence of the man.
For example, we have N = 7 prisoners, and we decided to kill every k=2 people in the line. At the beginning, the line looks like this:
1 2 3 4 5 6 7
after the first round, 1 3 5 7 will be executed, we have
2 4 6
and then, we will kill 2 6 in the second round. At last 4 will be executed. So, you need to output 1 3 5 7 2 6 4. Easy, right?
But the output maybe too large, we will give you Q queries, each one contains a number m, you need to tell me the m-th number in the death sequence.
[align=left]Input[/align] Multiple cases. The first line contains a number T, means the number of test case. For every case, there will be three integers N (1<=N<=3000000), K(1<=K), and Q(1<=Q<=1000000), which indicate the number of prisoners, the step length of killing, and the number of query. Next Q lines, each line contains one number m(1<=m<=n).
[align=left]Output[/align] For each query m, output the m-th number in the death sequence.
[align=left]Sample Input[/align]
[align=left]Sample Output[/align]
题目大意:
有 n 个人排成一列编号从 1−n,每次杀第一个人,然后是从第 i∗k+1 个人一直杀到最后,然
后剩下的人在重新编号从 1~x。按照上面的方式继续杀。问第 i 次杀的是谁,输出序号。
解题思路:
首先将 n 个人从 0 开始编号,然后定义一个 pair<int,int> 分别表示:
first:i 是在第 p[i].first轮 死的
second: i 是在第 p[i].first轮 第 p[i].second 死的
然后第一轮如果满足 i MOD k==0 的话,那么 p[i].first=0,p[i].second=i/k+1 否
则的话,根据前面的 i/k+1 的关系满足一下公式:
p[i].first = p[i−i/k−1].first+1;
p[i].second = p[i−i/k−1].second;
然后再用一个 sum 数组,sum[i] 表示 第 i 轮 一共死多少人,最后统计一下就行了。
Death Sequence
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 379 Accepted Submission(s): 163
[align=left]Problem Description[/align] You may heard of the Joseph Problem, the story comes from a Jewish historian living in 1st century. He and his 40 comrade soldiers were trapped in a cave, the exit of which was blocked by Romans. They chose suicide over capture and decided that they would form a circle and start killing themselves using a step of three. Josephus states that by luck or maybe by the hand of God, he and another man remained the last and gave up to the Romans.
Now the problem is much easier: we have N men stand in a line and labeled from 1 to N, for each round, we choose the first man, the k+1-th one, the 2*k+1-th one and so on, until the end of the line. These poor guys will be kicked out of the line and we will execute them immediately (may be head chop, or just shoot them, whatever), and then we start the next round with the remaining guys. The little difference between the Romans and us is, in our version of story, NO ONE SURVIVES. Your goal is to find out the death sequence of the man.
For example, we have N = 7 prisoners, and we decided to kill every k=2 people in the line. At the beginning, the line looks like this:
1 2 3 4 5 6 7
after the first round, 1 3 5 7 will be executed, we have
2 4 6
and then, we will kill 2 6 in the second round. At last 4 will be executed. So, you need to output 1 3 5 7 2 6 4. Easy, right?
But the output maybe too large, we will give you Q queries, each one contains a number m, you need to tell me the m-th number in the death sequence.
[align=left]Input[/align] Multiple cases. The first line contains a number T, means the number of test case. For every case, there will be three integers N (1<=N<=3000000), K(1<=K), and Q(1<=Q<=1000000), which indicate the number of prisoners, the step length of killing, and the number of query. Next Q lines, each line contains one number m(1<=m<=n).
[align=left]Output[/align] For each query m, output the m-th number in the death sequence.
[align=left]Sample Input[/align]
1 7 2 7 1 2 3 4 5 6 7
[align=left]Sample Output[/align]
1 3 5 7 2 6 4
题目大意:
有 n 个人排成一列编号从 1−n,每次杀第一个人,然后是从第 i∗k+1 个人一直杀到最后,然
后剩下的人在重新编号从 1~x。按照上面的方式继续杀。问第 i 次杀的是谁,输出序号。
解题思路:
首先将 n 个人从 0 开始编号,然后定义一个 pair<int,int> 分别表示:
first:i 是在第 p[i].first轮 死的
second: i 是在第 p[i].first轮 第 p[i].second 死的
然后第一轮如果满足 i MOD k==0 的话,那么 p[i].first=0,p[i].second=i/k+1 否
则的话,根据前面的 i/k+1 的关系满足一下公式:
p[i].first = p[i−i/k−1].first+1;
p[i].second = p[i−i/k−1].second;
然后再用一个 sum 数组,sum[i] 表示 第 i 轮 一共死多少人,最后统计一下就行了。
/** 2016 - 08 - 18 下午 Author: ITAK Motto: 今日的我要超越昨日的我,明日的我要胜过今日的我, 以创作出更好的代码为目标,不断地超越自己。 **/ #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <set> using namespace std; typedef long long LL; typedef unsigned long long ULL; const int INF = 1e9+5; const int MAXN = 3e6+5; const int MOD = 1e9+7; const double eps = 1e-7; const double PI = acos(-1); using namespace std; LL Scan_LL()///输入外挂 { LL res=0,ch,flag=0; if((ch=getchar())=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; return flag?-res:res; } int Scan_Int()///输入外挂 { int res=0,ch,flag=0; if((ch=getchar())=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; return flag?-res:res; } void Out(LL a)///输出外挂 { if(a>9) Out(a/10); putchar(a%10+'0'); } pair <int,int> p[MAXN]; /** first:i 是在第 p[i].first轮 死的 second: i 是在第 p[i].first轮 第 p[i].second 死的 **/ int sum[MAXN], ans[MAXN]; /** sum: 第 i 轮 一共死多少人 **/ void Init(int n, int k) { for(int i=0; i<n; i++) { if(i%k == 0) { p[i].first = 0; p[i].second = i/k+1; ///cout<<"i = "<<i<<" first = "<<p[i].first<<" second = "<<p[i].second<<endl; } else { p[i].first = p[i-i/k-1].first+1; p[i].second = p[i-i/k-1].second; ///cout<<"i = "<<i<<" first = "<<p[i].first<<" second = "<<p[i].second<<endl; } } int tmp = n-1, cnt = 0; sum[0] = 0; while(tmp) { cnt++; sum[cnt] = sum[cnt-1] + tmp/k+1; tmp = tmp-(tmp-1)/k-1; } for(int i=0; i<n; i++) ans[sum[p[i].first]+p[i].second] = i+1; } int main() { int T, n, k, q; T = Scan_Int(); while(T--) { n = Scan_Int(); k = Scan_Int(); q = Scan_Int(); Init(n, k); while(q--) { int x; x = Scan_Int(); printf("%d\n",ans[x]); } } return 0; }
相关文章推荐
- hdu 5860 Death Sequence(2016 Multi-University Training Contest 10——递推)
- 2016 Multi-University Training Contest 3 hdu 5752 Sqrt Bo【思维】
- (HDU 5742) It's All In The Mind <思维水题> 2016 Multi-University Training Contest 2
- 2016 Multi-University Training Contest 4 hdu 5775 Bubble Sort【树状数组+思维】
- hdu 5742 It's All In The Mind(2016 Multi-University Training Contest 2——思维题)
- hdu 5858 Hard problem(2016 Multi-University Training Contest 10——数学题)
- hdu 5867 Water problem(2016 Multi-University Training Contest 10——水题)
- (HDU 5744)Keep On Movin <回文数,思维水题> 2016 Multi-University Training Contest 2
- hdu 5802 Windows 10(2016 Multi-University Training Contest 6——贪心+dfs)
- hdu 5744 Keep On Movin(2016 Multi-University Training Contest 2——回文串,思维题)
- HDU 5861 Road (线段树) 2016 Multi-University Training Contest 10
- 2016 Multi-University Training Contest 3 hdu 5753 Permutation Bo【打表+递推】
- hdu 5861Road(2016 Multi-University Training Contest 10——线段树+扫描线)
- 2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树区间更新+差分数组)
- (HDU 5802)2016 Multi-University Training Contest 6 Windows 10 (贪心)
- hdu 5733 tetrahedron(2016 Multi-University Training Contest 1计算几何)
- 2016 Multi-University Training Contest 1 1011 hdu 5733 四面体内切球
- 2015 Multi-University Training Contest 10 hdu 5406 CRB and Apple
- hdu 5410 CRB and His Birthday 背包问题 2015 Multi-University Training Contest 10
- 2015 Multi-University Training Contest 10 hdu 5407 CRB and Candies