NOIP2013提高組複賽 轉圈遊戲 解題報告

2021-07-04 12:11:49 字數 3050 閱讀 2914

n 個小夥伴(編號從 0 到 n-1)圍坐一圈玩遊戲。按照順時針方向給 n 個位置編號,從0 到 n-1。最初,第 0 號小夥伴在第 0 號位置,第 1 號小夥伴在第 1 號位置,……,依此類推。

遊戲規則如下:每一輪第 0 號位置上的小夥伴順時針走到第 m 號位置,第 1 號位置小夥伴走到第 m+1 號位置,……,依此類推,第n − m號位置上的小夥伴走到第 0 號位置,第n-m+1 號位置上的小夥伴走到第 1 號位置,……,第 n-1 號位置上的小夥伴順時針走到第m-1 號位置。

現在,一共進行了 10^k 輪,請問 x 號小夥伴最後走到了第幾號位置。

輸入共 1 行,包含 4 個整數 n、m、k、x,每兩個整數之間用乙個空格隔開。

輸出共 1 行,包含 1 個整數,表示 10^k 輪後 x 號小夥伴所在的位置編號。

10 3 4 5
5
每個測試點1s。

對於 30%的資料,0 < k < 7; 

對於 80%的資料,0 < k < 10^7; 

對於 100%的資料,1 < n < 1,000,000,0 < m < n,1 <= x <=n,0 < k < 10^9。

noip 2013 提高組 day 1

簡單分析:

顯然有環(即轉圈的情況),即相當於從出發點直接走a個點,a:=(m*10^k) mod n【10^k這樣輸入是錯誤的】;

而題目資料太大,使用普通方法時間無法通過(我試了一下,能過百分之30左右)

所以想到優化10^k時的運算,即快速冪

**如下:program circle;

varn,m,x,dx:longint;

k:longint;

function kuaisumi(a,b,p:longint):longint;

var快速冪,核心操作就是轉化二進位制  

t,r:longint;

begin

r:=1;

t:=a;

while b>0 do

begin

if (b and 1)=1 then r:=r*t mod p;

t:=t*t mod p;

b:=b shr 1;

end;

exit(r);

end;

begin

assign(input,'write.in');

reset(input);

assign(output,'write.out');

rewrite(output);

readln(n,m,k,x);

dx:=kuaisumi(10,k,n);

dx:=(dx*m mod n+x) mod n;(化簡圈數)

writeln(dx);

close(input);

close(output);

end.

更短的**(方法相同)

program circle;

var a,n,y,k,m,x:longint;

begin

readln(n,m,k,x);

a:=m; y:=10;

while k<>0 do

begin

if k and 1=1

then a:=(a*y) mod n;

y:=y*y mod n;

k:=k shr 1;

end;

write((a+x)mod n);

end.

簡單分析:

顯然有環(即轉圈的情況),即相當於從出發點直接走a個點,a:=(m*10^k) mod n【10^k這樣輸入是錯誤的】;

而題目資料太大,使用普通方法時間無法通過(我試了一下,能過百分之30左右)

所以想到優化10^k時的運算,即快速冪

**如下:program circle;

varn,m,x,dx:longint;

k:longint;

function kuaisumi(a,b,p:longint):longint;

var

快速冪,核心操作就是轉化二進位制  

t,r:longint;

begin

r:=1;

t:=a;

while b>0 do

begin

if (b and 1)=1 then r:=r*t mod p;

t:=t*t mod p;

b:=b shr 1;

end;

exit(r);

end;

begin

assign(input,'write.in');

reset(input);

assign(output,'write.out');

rewrite(output);

readln(n,m,k,x);

dx:=kuaisumi(10,k,n);

dx:=(dx*m mod n+x) mod n;(化簡圈數)

writeln(dx);

close(input);

close(output);

end.

更短的**(方法相同)

program circle;

var a,n,y,k,m,x:longint;

begin

readln(n,m,k,x);

a:=m; y:=10;

while k<>0 do

begin

if k and 1=1

then a:=(a*y) mod n;

y:=y*y mod n;

k:=k shr 1;

end;

write((a+x)mod n);

end.

轉圈遊戲 NOIP2013提高組

時間限制 1.0s 記憶體限制 256.0mb n 個小夥伴 編號從 0 到 n 1 圍坐一圈玩遊戲。按照順時針方向給 n 個位置編號,從0 到 n 1。最初,第 0 號小夥伴在第 0 號位置,第 1 號小夥伴在第 1 號位置,依此類推。遊戲規則如下 每一輪第 0 號位置上的小夥伴順時針走到第 m ...

NOIP2013提高組 花匠

花匠棟棟種了一排花,每株花都有自己的高度。花兒越長越大,也越來越擠。棟棟決定把這排中的一部分花移走,將剩下的留在原地,使得剩下的花能有空間長大,同時,棟棟希望剩下的花排列得比較別緻。具體而言,棟棟的花的高度可以看成一列整數h 1,h 2,h n。設當一部分花被移走後,剩下的花的高度依次為g 1,g ...

NOIP2013提高組解析

題目描述 轉圈遊戲 火柴排隊 貨車運輸 積木大賽 花匠 華容道day1 轉圈遊戲 最終位置實際上就是 x m 10 k n 快速冪即可。include includeusing namespace std int n,m,k,x int power int k int main 火柴排隊 根據感覺可...