蘭橋杯 2023 第 14 回省大会 本当の質問 - 小さな数字 - 解決策

目次

蘭橋杯 2023 第 14 回省大会 本当の質問 - 数字が小さい

質問の説明

入力フォーマット

出力フォーマット

サンプル入力

サンプル出力

ヒント

【アイデアの分析】

【コード】


蘭橋杯 2023 第 14 回省大会 本当の質問 - 数字が小さい

制限時間: 3 秒 メモリ制限: 320MB 送信数: 895 解決数: 303

質問の説明

蘭橋杯 2023 第 14 回省大会 本当の質問 - 数字が小さい

Xiaolan には長さ n の文字列があり、0 〜 9 の数字のみで構成され、添字は 0 から n − 1 までです。n 桁の 10 進数 num と考えることができます。Xiaolan は次から開始できます。 num から連続する部分文字列を選択します。部分文字列を最大 1 回反転します。Xiaolan は、選択した部分文字列を反転して元の位置に戻し、条件 numnew < num を満たす新しい数値 numnew を取得したいと考えています。異なる部分文字列の選択オプションがいくつあるか計算するのを手伝ってください。 num 内の 2 つの部分文字列は完全に同じではないため、それらは異なるソリューションとみなされます。

先行ゼロの存在を許可することに注意してください。つまり、数値の最上位ビットが 0 であってもよく、これは正当です。

入力フォーマット

numを表す長さnの文字列(0~9の数字のみを含む)を含む行を入力します。

添字は左から右に 0 〜 n − 1 です。

出力フォーマット

出力の 1 行には、答えを表す整数が含まれます。

サンプル入力

コピー

210102

サンプル出力

コピー

8

ヒント

合計 8 つの異なるオプションがあります。

1) 選択された部分文字列インデックスは 0 〜 1 であり、その逆の numnew = 120102 < 210102;

2) 選択された部分文字列インデックスは 0 〜 2 であり、反転された numnew = 012102 < 210102;

3) 選択された部分文字列インデックスは 0 〜 3 であり、反転された numnew = 101202 < 210102;

4) 選択された部分文字列インデックスは 0 〜 4 であり、反転された numnew = 010122 < 210102;

5) 選択された部分文字列インデックスは 0 〜 5 であり、反転された numnew = 201012 < 210102;

6) 選択された部分文字列インデックスは 1 〜 2 であり、反転された numnew = 201102 < 210102;

7) 選択された部分文字列の添字は 1 〜 4 であり、その反転された numnew = 201012 < 210102;

8) 選択された部分文字列インデックスは 3 〜 4 であり、反転された numnew = 210012 < 210102;

評価ケースの 20% では、1 ≤ n ≤ 100。

評価ケースの 40% では、1 ≤ n ≤ 1000。

すべての評価ケースで、1 ≤ n ≤ 5000。

【アイデアの分析】

すべての可能性をたどる 部分文字列 i -- j については、3 つの状況が考えられます。

(1) str[i] > str[j]であれば交換可能です。

(2) str[i] < str[j]の場合は交換できません。

(3) str[i] == str[j] の場合、部分文字列 i+1 --- j-1 が交換できるかどうかを検討し、交換できる場合はアトミック文字列を交換でき、そうでない場合は交換できません。交換した。

【コード】

import java.util.Scanner;

/**
 * @ProjectName: study3
 * @FileName: Ex2
 * @author:HWJ
 * @Data: 2023/9/17 9:22
 */
public class Ex2 {
    static int ans = 0;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String s = input.next();
        char[] str = s.toCharArray();
        for (int right = 1; right < str.length; right++) {
            for (int left = 0; left < right; left++) {
                int L = left + 1;
                int R = right - 1;
                boolean loop = false;
                while (L < R){
                    if(str[L] > str[R]){
                        loop = true;
                        break;
                    } else if (str[L] < str[R]) {
                        break;
                    }else {
                        L += 1;
                        R -= 1;
                    }
                }
                if (str[left] > str[right] || (loop && str[left] == str[right])){
                    ans++;
                }
            }
        }
        System.out.println(ans);
    }


}

おすすめ

転載: blog.csdn.net/weixin_73936404/article/details/132939396