1. 程式人生 > >2016 Multi-University Training Contest 10 || hdu 5860 Death Sequence(遞推+單線約瑟夫問題)

2016 Multi-University Training Contest 10 || hdu 5860 Death Sequence(遞推+單線約瑟夫問題)

ive alt 分析 while death src bool names 轉化

題目鏈接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5860

題目大意:給你n個人排成一列編號,每次殺第一個人第i×k+1個人一直殺到沒的殺。然後剩下的人重新編號從1~剩余的人數。按照上面的方式殺。問第幾次殺的是誰。

分析

一輪過後和原來問題比只是人的編號發生變化,故可以轉化為子問題求解,不妨設這n個人的編號是0~n-1,對於第i個人,如果i%k=0,那麽這個人一定是第一輪出列的第i/k+1個人;如果i%k!=0,那麽這個人下一輪的編號就是i-i/k-1;

技術分享圖片
#include<stdio.h>
#include<algorithm>
using
namespace std ; #define N 3000000+10 struct no { int d ; ///表示哪一輪被殺 int num ; ///表示當前輪第幾個被殺 int p ; ///表示本身是幾號 }s[N]; bool cmp(no a , no b) { if(a.d==b.d) return a.num<b.num; return a.d<b.d; } int main( ) { int T,n,k,q,m; scanf("%d",&T); while(T--) { scanf(
"%d %d %d",&n,&k,&q); s[0].num=1; for(int i=0 ; i<n ; i++) { s[i].p=i+1; if(i%k==0) { s[i].d=1; if(i==0) continue; s[i].num=s[i-k].num+1; } else
{ s[i].d=s[i-i/k-1].d+1; s[i].num=s[i-i/k-1].num; } } sort(s,s+n,cmp); while(q--) { scanf("%d",&m); m--; printf("%d\n",s[m].p); } } }
View Code

2016 Multi-University Training Contest 10 || hdu 5860 Death Sequence(遞推+單線約瑟夫問題)