HJ64 MP3 カーソル位置 ●●
説明する
MP3 プレーヤーの画面は小さいため、曲リストを表示するときに各画面に数曲しか表示できず、すべての曲を参照するには上下キーを押す必要があります。処理を簡略化するため、各画面に表示できる曲は 4 曲のみとし、カーソルの初期位置は 1 曲目とします。
ここで、上下キーでカーソルの動きを制御して曲のリストを参照するための制御ロジックは次のとおりです。
1.総曲数が 4 以下の場合は、ページをめくる必要はなく、カーソル位置を移動するだけです。
カーソルが最初の曲にある場合は上キーを押すと最後の曲に移動し、カーソルが最後の曲にある場合は下キーを押すと最初の曲にカーソルが移動します。
他の場合には、ユーザーが上キーを押すとカーソルは前の曲に移動し、ユーザーが下キーを押すとカーソルは次の曲に移動します。
2.合計曲数が 4 曲を超える場合 (合計 10 曲を例にします):
特別なページめくり: 画面に最初のページ (つまり、1 曲目から 4 曲目まで) が表示されているとき、カーソルはオンになります。最初の曲とユーザー Up キーを押した後、画面に最後のページ (つまり 7 ~ 10 番目の曲を表示) が表示され、同時にカーソルが最後の曲に置かれます。同様に、画面に最後のページが表示され、カーソルが最後の曲にあり、ユーザーが下キーを押すと、画面に最初のページが表示され、カーソルが最初の曲に移動します。
一般的なページめくり: 画面に最初のページが表示されていない場合、カーソルが現在の画面に表示されている最初の曲にある場合、ユーザーが上キーを押すと、画面は現在の曲の前の曲から表示を開始します。とカーソルも前の曲に移動します。現在の画面の最後の曲にカーソルがあるときの下キーの処理も同様です。
それ以外の場合は、ページをめくる必要はなく、カーソルを移動するだけで済みます。
データ範囲:コマンド長1 ≤ s ≤ 100 1\le s\le 1001≤s≤100、曲数1 ≤ n ≤ 150 1\le n \le 1501≤n≤150
上級: 時間計算量:O ( n ) O(n)O ( n )、空間計算量:O ( n ) O(n)O ( n )
説明を入力してください:
1 曲数を入力
2 コマンド U または D を入力
出力の説明:
1 現在のリストを出力します。
2 現在選択されている曲を出力します。
例
入力:
10
UUUU
出力:
7 8 9 10
7
答え
1. シミュレーション
変数:
pageNum
n で決定される表示可能な最大行数を記録 (1 ~ 4)、
first
現在のページの最初の番号を記録、
idx
現在のカーソル位置 (1 ~ pageNum) を記録、
curr
現在のカーソルが指す番号を記録に。
カーソルの移動中、上記の変数は維持され、具体的な状況は次のとおりです。
- 最初の行が上がり、最初の行を変更します:
– 最初の行が 1、ページを最後までめくります;
– 最初の行がその他、スクロールします - 最後の行が下に進み、最初の行が変更されます。
– 最後の行は n、ページをめくって先頭へ
– 最後の行はその他、スクロール - カーソルを中央の行の上または下に移動します。
時間計算量: O ( n ) O(n)O ( n )
空間複雑さ:O ( 1 ) O(1)○ (1)
#include<iostream>
#include<string>
using namespace std;
#define maxNum 4
int main(){
int n;
string str;
while(cin >> n >> str){
if(n == 1){
cout << 1 << endl << 1;
continue;
}
int pageNum = maxNum;
if(n <= maxNum) pageNum = n; // pageNum 记录显示的最大行数
int first = 1, idx = 1, curr = 1;
for(char ch: str){
if(1 == idx && ch == 'U'){
// 首行往上,需要变换首行
if(1 == curr){
// 首行为1,翻页,到最尾
idx = pageNum;
first = n - pageNum + 1;
curr = n;
}else{
// 首行为其他,滚动
--curr;
--first;
}
}else if(pageNum == idx && ch == 'D'){
// 尾行往下,变换首行
if(n == curr){
// 尾行为n,翻页,到开头
idx = 1;
first = 1;
curr = 1;
}else{
// 尾行为其他,滚动
++curr;
++first;
}
}else{
if(ch == 'D'){
// 移动光标
++idx;
++curr;
}else if(ch == 'U'){
--idx;
--curr;
}
}
}
for(int i = 0; i < pageNum; ++i){
cout << first + i << " ";
}
cout << endl << curr << endl;
}
return 0;
}