BZOJ 1965 [AHOI2005]洗牌
阿新 • • 發佈:2017-10-05
sin 空格 == cdn 長度 技術分享 math 參加 urn
題目描述
為了表彰小聯為Samuel星球的探險所做出的貢獻,小聯被邀請參加Samuel星球近距離載人探險活動。
由於Samuel星球相當遙遠,科學家們要在飛船中度過相當長的一段時間,小聯提議用撲克牌打發長途旅行中的無聊時間。玩了幾局之後,大家覺得單純玩撲克牌對於像他們這樣的高智商人才來說太簡單了。有人提出了撲克牌的一種新的玩法。
對於撲克牌的一次洗牌是這樣定義的,將一疊N(N為偶數)張撲克牌平均分成上下兩疊,取下面一疊的第一張作為新的一疊的第一張,然後取上面一疊的第一張作為新的一疊的第二張,再取下面一疊的第二張作為新的一疊的第三張……如此交替直到所有的牌取完。
如果對一疊6張的撲克牌1 2 3 4 5 6,進行一次洗牌的過程如下圖所示:
從圖中可以看出經過一次洗牌,序列1 2 3 4 5 6變為4 1 5 2 6 3。當然,再對得到的序列進行一次洗牌,又會變為2 4 6 1 3 5。
遊戲是這樣的,如果給定長度為N的一疊撲克牌,並且牌面大小從1開始連續增加到N(不考慮花色),對這樣的一疊撲克牌,進行M次洗牌。最先說出經過洗牌後的撲克牌序列中第L張撲克牌的牌面大小是多少的科學家得勝。小聯想贏取遊戲的勝利,你能幫助他嗎?
輸入輸出格式
輸入格式:
輸入文件中有三個用空格間隔的整數,分別表示N,M,L
(其中0<N≤10^10 ,0 ≤M≤10^10,且N為偶數)。
輸出格式:
單行輸出指定的撲克牌的牌面大小。
輸入輸出樣例
輸入樣例#1:6 2 3輸出樣例#1:
6
題解:
這個題目,顯然一看到,有是一道置換的題目,老套路,我們找環,然後取模,再暴力跑就可以了。
代碼:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <iostream> #define MAXN 1010 using namespace std; int card[MAXN],a[MAXN]; int n,m,l; int main() { scanf("%d%d%d",&n,&m,&l); int mod=1,now; if(l%2==0) now=l/2; else now=(l+1)/2+n/2; while(now!=l){ if(now%2==0) now=now/2; else now=(now+1)/2+n/2; mod++; } m%=mod; while(m--){ if(now%2==0) now=now/2; else now=(now+1)/2+n/2; } printf("%d\n",now); return 0; }
BZOJ 1965 [AHOI2005]洗牌