{ }codelper
判定関数P0196

整ったロッカー番号

整理整頓が好きな学校は「整った番号」のロッカーを先に配る。
ある数を左の桁から読んだとき、どの桁の数字もすぐ左の桁の数字以上なら、整った番号である。
たとえば 1123、7、0 は整った番号で、1231(3 の次に 1)と 10 はそうではない。
一桁の数はすべて整った番号である。
一行目にロッカー番号の数 n、続く n 行に番号が一つずつ与えられる。
番号ごとに、整った番号なら "はい"、そうでなければ "いいえ" を一行に出力せよ。
最後の行には整った番号の個数を出力せよ。
番号を一つ受け取り、整った番号かどうかを真偽値で返す関数を作って使おう。

入力
1 ≤ n ≤ 1,000。
0 ≤ 番号 < 10^18(最大 18 桁)で、0 でなければ先頭の桁は 0 ではない。
出力
n+1 行:番号ごとに yes か no、最後の行に yes の個数
例 1 · stdin
4
1123
1231
7
10
stdout
はい
いいえ
はい
いいえ
2
main.py
入力(stdin)

実行すると、これらの行が順に input()・標準入力に渡されます(実行中に入力を求めません)。

$ 準備完了

コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。

ほかの言語では?言語別の解答を見る · 8 言語の解答

真偽値を返す関数は「おかしな所を一つでも見つけたらすぐ偽、最後まで見てはじめて真」と組みます。
真偽値の型の名前は言語ごとに違います:Python bool(True/False)、JS・TS boolean、Java boolean、C# bool、C++ bool、C は <stdbool.h> の bool(昔の C は int で 0・1 を返していました)、Craykon は値 真/偽 を 返す で返します。
Python なら all(a <= b for a, b in zip(s, s[1:])) の一行でも書けます。
数字の文字は文字コードの順がそのまま数の順なので、数に変えずに s[i] > s[i + 1] で直接比べてかまいません。
落とし穴は四つ:① ループの中で if おかしい: return False の後に else: return True を付けると、最初の組だけを見て真を返します(1231 が yes)。
② 同じ数字が続くもの(112)も整った番号です。
小さくなるときだけ偽なので、>= ではなく > で調べます。
③ JS の forEach の中の return false はコールバック一回を終えるだけで外側の関数は終わらないので、関数はいつも true を返します。
途中で抜けるには for ループか every を使います(Java・C# のラムダの中で return false を書くとそもそもコンパイルできません)。
④ 番号は最大 18 桁なので int(約 21 億まで)に入りません。
Java Integer.parseInt は例外を出し、C scanf("%d") はあふれます。
文字列として読めば大きさの心配はありません。

Pythonmain.py · 17 行
def is_tidy(s):    """왼쪽에서 오른쪽으로 숫자가 작아지는 곳이 한 번도 없으면 True"""    for i in range(len(s) - 1):        if s[i] > s[i + 1]:            return False    return True  # 끝까지 다 본 뒤에야 참이라고 말할 수 있다  n = int(input())count = 0for _ in range(n):    if is_tidy(input().strip()):        print("はい")        count += 1    else:        print("いいえ")print(count)
JavaScriptmain.js · 23 行
const lines = require("fs").readFileSync(0, "utf8").split("\n"); // 왼쪽에서 오른쪽으로 숫자가 작아지는 곳이 한 번도 없으면 truefunction isTidy(s) {  for (let i = 0; i + 1 < s.length; i++) {    if (s[i] > s[i + 1]) return false;  }  return true;} const n = Number(lines[0]);const out = [];let count = 0;for (let i = 1; i <= n; i++) {  if (isTidy(lines[i].trim())) {    out.push("はい");    count++;  } else {    out.push("いいえ");  }}out.push(count);console.log(out.join("\n"));
TypeScriptmain.ts · 25 行
import { readFileSync } from "node:fs"; const lines: string[] = readFileSync(0, "utf8").split("\n"); // 왼쪽에서 오른쪽으로 숫자가 작아지는 곳이 한 번도 없으면 truefunction isTidy(s: string): boolean {  for (let i = 0; i + 1 < s.length; i++) {    if (s[i] > s[i + 1]) return false;  }  return true;} const n: number = Number(lines[0]);const out: string[] = [];let count = 0;for (let i = 1; i <= n; i++) {  if (isTidy(lines[i].trim())) {    out.push("はい");    count++;  } else {    out.push("いいえ");  }}out.push(String(count));console.log(out.join("\n"));
JavaMain.java · 28 行
import java.io.*; public class Main {    // 왼쪽에서 오른쪽으로 숫자가 작아지는 곳이 한 번도 없으면 true    static boolean isTidy(String s) {        for (int i = 0; i + 1 < s.length(); i++) {            if (s.charAt(i) > s.charAt(i + 1)) return false;        }        return true;    }     public static void main(String[] args) throws IOException {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        int n = Integer.parseInt(br.readLine().trim());        StringBuilder sb = new StringBuilder();        int count = 0;        for (int i = 0; i < n; i++) {            if (isTidy(br.readLine().trim())) {                sb.append("はい\n");                count++;            } else {                sb.append("いいえ\n");            }        }        sb.append(count).append('\n');        System.out.print(sb);    }}
C#Main.cs · 36 行
using System;using System.Text; class Program{    // 왼쪽에서 오른쪽으로 숫자가 작아지는 곳이 한 번도 없으면 true    static bool IsTidy(string s)    {        for (int i = 0; i + 1 < s.Length; i++)        {            if (s[i] > s[i + 1]) return false;        }        return true;    }     static void Main()    {        int n = int.Parse(Console.ReadLine()!.Trim());        var sb = new StringBuilder();        int count = 0;        for (int i = 0; i < n; i++)        {            if (IsTidy(Console.ReadLine()!.Trim()))            {                sb.Append("はい\n");                count++;            }            else            {                sb.Append("いいえ\n");            }        }        sb.Append(count).Append('\n');        Console.Write(sb);    }}
C++main.cpp · 27 行
#include <iostream>#include <string> // 왼쪽에서 오른쪽으로 숫자가 작아지는 곳이 한 번도 없으면 truebool isTidy(const std::string& s) {    for (size_t i = 0; i + 1 < s.size(); i++) {        if (s[i] > s[i + 1]) return false;    }    return true;} int main() {    std::ios::sync_with_stdio(false);    int n, count = 0;    std::string s;    std::cin >> n;    for (int i = 0; i < n; i++) {        std::cin >> s;        if (isTidy(s)) {            std::cout << "はい\n";            count++;        } else {            std::cout << "いいえ\n";        }    }    std::cout << count << "\n";}
Cmain.c · 29 行
#include <stdbool.h>#include <stdio.h>#include <string.h> // 왼쪽에서 오른쪽으로 숫자가 작아지는 곳이 한 번도 없으면 truebool is_tidy(const char *s) {    size_t len = strlen(s);    for (size_t i = 0; i + 1 < len; i++) {        if (s[i] > s[i + 1]) return false;    }    return true;} int main(void) {    int n, count = 0;    char s[32];  // 18자리까지라 문자열로 읽는다    scanf("%d", &n);    for (int i = 0; i < n; i++) {        scanf("%31s", s);        if (is_tidy(s)) {            puts("はい");            count++;        } else {            puts("いいえ");        }    }    printf("%d\n", count);    return 0;}
Craykonmain.cray · 28 行
// 왼쪽에서 오른쪽으로 숫자가 작아지는 곳이 한 번도 없으면 참정리된번호인가(s){    繰り返す (i = 0; i + 1 < s.長さ; i++)    {        もし (s[i] > s[i + 1])        {            返す 偽;        }    }    返す 真; // 끝까지 다 본 뒤에야 참이라고 말할 수 있다} n = コンソール.行読み().数に();count = 0;繰り返す (k = 0; k < n; k++){    もし (정리된번호인가(コンソール.行読み().空白除去()))    {        コンソール.書く("はい");        count++;    }    でなければ    {        コンソール.書く("いいえ");    }}コンソール.書く(count);