上一篇(https://iobaka.com/blog/82.html)文章解决了该游戏 D 难度下的地区问题,这一篇开始解决难度 C 的问题。
上手
问题1:機械の総合病院 [MISSION LEVEL: C]
PAIZA病院のシステムを解析します。
不正アクセスを試みるクラッカーからユーザーを守るために、ユーザーが設定するパスワードが十分に複雑であるようにしなくてはなりません。
PAIZA病院は、パスワードの複雑さの条件として以下の 3 つを定めました。・長さが 6 以上
・英字と数字の両方を含む必要がある
・同じ文字を 3 つ以上連続で使用することはできないなお、英字の大文字と小文字は区別する必要はありません。 パスワードの候補が入力として与えられるので、複雑さの条件をすべて満たす場合は
"Valid"、そうでない場合は "Invalid" と出力してください。例えば、入力例 1 で与えられる 7Caaad9 は 1 つ目の条件と 2 つ目の条件を満たしますが、aaa と 3
つ以上同じ文字が連続で使用されているため、複雑さの条件をすべて満たしません。
解释:
解析PAIZA医院的系统。
为了保护用户免受未经授权访问的入侵者的侵害,您必须确保您设置的密码足够复杂。
PAIZA医院建立了以下三个条件保证密码的复杂性:
- 长度 6 个字符以上
- 同时含有中英文两种字符
- 同种字符不能连续使用 3 次
不用区分大写字母和小写字母。
密码符合复杂度时输出『Valid』,不符合时则输出『Invalid』。
例如,密码 7Caaad9 满足条件1和2,但是有同种连续字符 aaa ,则不符合条件3,输出 Invalid。
解答:
这道题采用遍历字符串解决,设定两个开关,分别是字母开关和数字开关。
当遍历的字符是字母或数字时,则打开对应开关。
然后存放数字或字母连续出现的次数,达到3次则直接输出 Invalid 退出程序。
遍历结束后,判断字母数字以及长度是否符合,符合则输出 Valid,否则输出 Invalid 。
<?php
// 自分の得意な言語で
// Let's チャレンジ!!
$input_lines = fgets(STDIN);
$num_have = false;
$letter_have = false;
// 字符出现次数计数器
$letter_max_same = 0;
// 字符预存
$letter_same = '';
// 判断长度
for ($i = 0; $i < strlen($input_lines); $i++) {
$str = substr($input_lines, $i, 1);
// 判断符合数字或字母条件
if(is_numeric($str)) {
$num_have = true;
}
else {
$letter_have = true;
}
// 判断同种字符连续出现次数
if(strtolower($str) == $letter_same) {
$letter_max_same++;
// 如果连续出现3次,则输出 Invalid
if($letter_max_same == 3) {
echo 'Invalid';
exit;
}
}
// 重置出现次数
else {
$letter_same = $str;
$letter_max_same = 1;
}
}
if($letter_have && $num_have && strlen($input_lines) >= 6) {
echo 'Valid';
}
else {
echo 'Invalid';
}
?>
问题2:学べない学校 [MISSION LEVEL: C]
学校の子どもたちがじゃんけんをしています。特にA くんと B くんはじゃんけんが大好きで毎日しており、それぞれ「自分のほうが強い」と言い合っています。
そこであなたは二人のじゃんけんの結果を記録し、どちらが強いのか判定するプログラムを作ってあげることにしました。
これからAくんとBくんは N 回じゃんけんをします。A くんと B くんの出した手が N 回分与えられるので、A くんが勝った回数と B くんが勝った回数を数えるプログラムを作成してください。
じゃんけんの手はグー、チョキ、パーのいずれかで、 グーはチョキに勝ち、チョキはパーに勝ち、パーはグーに勝ちます。
入力では
・グーは "g"
・チョキは "c"
・パーは "p"で表現されます。
入力例 1 を図示すると以下のようになります。
解释:
学校里的熊孩子在玩石头剪刀布,A和B都说自己更厉害。
所以你写了个程序记录猜拳结果,来看谁更强。
A和B会进行N次对局,计算A和B分别赢得的次数。
石头是 g, 剪刀是 c, 布是 p 。
解答:
switch语句判断一下,然后分类计算即可。
<?php
// 自分の得意な言語で
// Let's チャレンジ!!
$a = 0;
$b = 0;
$line = fgets(STDIN);
for ($i = 0; $i < $line; $i++) {
$str = '';
$str = fgets(STDIN);
$str = explode(' ', $str);
$str[1] = substr($str[1], 0, 1);
switch ($str[0]) {
case 'g':
if($str[1] == 'c') $a++;
if($str[1] == 'p') $b++;
break;
case 'c':
if($str[1] == 'g') $b++;
if($str[1] == 'p') $a++;
break;
case 'p':
if($str[1] == 'g') $a++;
if($str[1] == 'c') $b++;
break;
}
unset($str);
}
echo $a.PHP_EOL.$b;
?>
问题3:荒れ果てたショップ [MISSION LEVEL: C]
あなたは今ファイルの管理をしようとしています。 各ファイルは番号で管理されていますが、一目でどの番号かわかるように、番号の左に適当な数の
0 を埋め込んで、番号の長さを固定することにしました。例えば、番号の長さを 3 で固定したい場合、0 は 000, 4 は 004, 13 は 013, 144 は 144
というようにファイル番号をつけます。 3 つの整数 N, A, B が与えられます。 A 以上 B 以下の数それぞれについて、番号の長さが
N にするようなゼロ埋めをするとファイル番号はどのように表示されるかを出力してください。例えば、入力例 1 を説明する図は以下のようになります。
この例では、9, 10, 11 の 3 つの数を、すべて長さ 3 の番号にするために左に 0 を埋めることを考えます。
・9 は 1 桁の数なので、長さ 3 の番号にするには、2 つの 0 を左から埋める必要があります。
・10, 11 は 2 桁の数なので、長さ 3 の番号にするには、1 つの 0 を左から埋める必要があります。
解释:
你正在管理文件。
每个文件由数字进行管理,为了让文件一目了然,需要在长度不足的数字前的空位补上0。
例如,数字长度固定为3时,0需要补为000,4为004,13为013,144为144等。
给三个整数 N,A,B ,需要输出 A~B 的全部文件编号,并按照长度 N 进行补0。
解答:
这道题需要从 A 循环到 B 进行输出,并且对数字进行长度 N 的补齐。
将 N 和数字的长度进行相减,然后得出的数字就是要补 0 的个数,然后循环在前面补 0 就能解决。
<?php
// 自分の得意な言語で
// Let's チャレンジ!!
$input_lines = fgets(STDIN);
$input_lines = explode(' ', $input_lines);
$result = [];
// 从 A 循环到 B
for ($i = (int)$input_lines[1]; $i <= (int)$input_lines[2]; $i++) {
$c = $i;
// 计算要补多少个 0
$zero_len = $input_lines[0] - strlen((string)$i);
// 循环补 0
for ($j = 0; $j < $zero_len; $j++) {
$c = '0'.$c;
}
$result[] = $c;
}
foreach ($result as $value) {
echo $value.PHP_EOL;
}
?>
结尾
下一节开始解决难度B的题目。