翻幣問題 ssl 1457

2021-07-25 14:18:38 字數 1645 閱讀 9389

題意:

description

有n個硬幣(6<=n<=20000)全部正面朝上排成一排,每次將其中5個硬幣翻過來放在原位置,直到最後全部硬幣翻成反面朝上為止。試程式設計找出步數最少的翻法,輸出最少步數及翻法。

input

從鍵盤輸入乙個正整數n(6<=n<=20000),表示硬幣的數量。

output

第1行:乙個整數,表示最少步數 

第2行至最後一行:先是乙個整數,表示步驟序號(從0開始編號),後接乙個":",再接當前硬幣的狀態(用乙個整數表示正面朝上的硬幣的個數) 

sample input

6  (開始:6個硬幣正面朝上)

sample output

0:6   (第0步結果:6個硬幣正面朝上)

1:1   (第1步結果:1個硬幣正面朝上)

2:4   (第2步結果:4個硬幣正面朝上)

3:3   (第3步結果:3個硬幣正面朝上)

4:2   (第4步結果:2個硬幣正面朝上)

5:5   (第5步結果:5個硬幣正面朝上)

6:0   (第6步結果:0個硬幣正面朝上)

6     (最少用6步實現全部反面朝上)

hint

只輸出最少次數,其變化過程僅作參考

分析:這一題並沒有給出目標的位置,需要我們自己設定。我們可以用h陣列作為記錄當前正面硬幣的數量,則結果應當是正面硬幣數量為0。這樣一來就非常好做廣搜了,只需每一次都由頭指標所指向的位置進行判斷,可以則記錄下來,還需要判重否則程式將陷入死迴圈中。最後遞迴回去輸出每一步的值並統計總步數。

const

maxn=20000;

vars:array[1..maxn] of longint;

f:array[1..maxn] of longint;

n,d:longint;

procedure init;

begin

readln(n);

end;

procedure print(x:longint);

begin

if x=0 then exit;

print(f[x]);

inc(d);

end;

procedure bfs;

var h,i,j,t:longint;

begin

h:=0;t:=1;s[1]:=n;

repeat

inc(h);

for i:=0 to 5 do

if (s[h]>=i) and (n-s[h]>=5-i) then

begin

inc(t);

f[t]:=h;

s[t]:=s[h]-i+5-i;

for j:=1 to t-1 do

if s[j]=s[t] then begin

dec(t);

break;

end;

if s[t]=0 then begin

d:=0;

print(t);

writeln(d-1);

t:=0;

end;

end;

until h>=t;

end;

begin

init;

bfs;

end.

SSL 1457 翻幣問題

有n個硬幣 6 n 20000 全部正面朝上排成一排,每次將其中5個硬幣翻過來放在原位置,直到最後全部硬幣翻成反面朝上為止。試程式設計找出步數最少的翻法,輸出最少步數及翻法。從鍵盤輸入乙個正整數n 6 n 20000 表示硬幣的數量。第1行 乙個整數,表示最少步數 第2行至最後一行 先是乙個整數,表...

SSLOJ 1457 翻幣問題

有n個硬幣 6 n 20000 全部正面朝上排成一排,每次將其中5個硬幣翻過來放在原位置,直到最後全部硬幣翻成反面朝上為止。試程式設計找出步數最少的翻法,輸出最少步數及翻法。從鍵盤輸入乙個正整數n 6 n 20000 表示硬幣的數量。第1行 乙個整數,表示最少步數 第2行至最後一行 先是乙個整數,表...

翻幣問題 題解

有n個硬幣 6 n 20000 全部正面朝上排成一排,每次將其中5個硬幣翻過來放在原位置,直到最後全部硬幣翻成反面朝上為止。試程式設計找出步數最少的翻法,輸出最少步數及翻法。從鍵盤輸入乙個正整數n 6 n 20000 表示硬幣的數量。第1行 乙個整數,表示最少步數 第2行至最後一行 先是乙個整數,表...