[アルゴリズム/規格]1110号::プラス記号周期(C++)


に質問🏻 :: [110回]プラス記号周期


(緑色のテキストをクリックして問題に移動)


整数Nを受け入れます.入力Nの各ビット数を加算します.そして,与えられた数の右端ビット数と,先に求めたプロトコルの右端ビット数とを加算することで,新しい数字が形成される.元の数を返す周期の長さを計算するプログラムを作成してください.

アルゴリズム💻


10952号A+B-5号と同様、テストケースはありません.つまり、繰り返しの回数が分からないので、for文ではなくwhile文を使うべきです.
for文:繰り返し回数が正確に分かった場合
while文:繰り返し条件を設定する場合
条件を設定し、最初に入力した数字と同じ数字が表示された場合は、繰り返し終了を設定します.
条件をどのように設定するかがポイントです.
最初の試み:計算を10桁と1桁に分ける
結果:🚨コンパイルエラー+タイムアウト🚨
2回目の試行:1行に複数の変数が含まれないように変更
結果:正常に動作しました.
詳細コードは以下の通りです!

💡初めての試み💡


最初の試みは間違った答えだった.コードは次のとおりです.

#include <iostream>

using namespace std;

int main()
{

    int N, a, b;
    int cnt = 0;
    int sum = 0;

    cin >> N;

    a = N / 10;	//10의 자리 수
    b = N % 10;	//1의 자리 수

		//합이 N과 다르면 계속 반복
    while (sum != N) {
      
      	//1의 자리수와 10의 자리 수 더하기
        sum = a + b;
        a = b;	//10의 자리 수에 1을 대입
        b = sum % 10;	//
        cnt = cnt + 1;	//사이클의 길이 +1

    }
    cout << cnt;
    return 0;
}

=>これでは、プログラムが実行されないだけでなく、バックグラウンドサイトにコミットされると「タイムアウト」と誤認されます.
どうやって答えを修正すればいいですか?

💡2回目の試み💡


問題を一つ一つ解いてみよう.
  • N(0<=N<=99).
  • Nの各数値を加算します.
  • Nの右端ビット数は、先に求めたプロトコルの右端ビット数と新しい数に連結される.
  • 2~3回この過程を繰り返し、新数が元の数を返す周期数を求める.
  • N=26,周期はcntである.
    cnt各ビット数に新しい数12+6=86826+8=148438+4=12424+2=626を加える
    26から始まります.2+6=8.新しい数字は68です.6+8=14.新数は84です.8+4=12.新しい数字は42です.4+2=6.新しい数は26です.
    上の例は4回で元の数に戻ることができます.したがって、26の周期長は4である.
    .
    .
    .
    この例では、各ビット数に加算された値が1のビット数であり、前の1のビット数が10であることがわかります.
    問題の指紋を1つの文単位で分析し、コードの作成方法を説明します.
    1.N(0<=N<=99)と入力します.
    簡単!cinを用いて整数Nを受け入れる.
    2.Nの各ビット数を加算します.
    各ビット数を加算するには、/および%演算子を使用します.
    10の桁数は/,1の桁数は%である.
    N = N / 10 + N % 10 	//❶
    3.Nの右端の桁数と、先に求めたプロトコルの右端の桁数とを接続して、新しい数字を作成します.
    ①Nの右端桁
    𘸗1の桁数は,|𐥊4|で求めることができる.
    N % 10
    ②前記合意の右端桁
    合が2桁の場合、右端の桁を求める.同様に、%を使用します.
    (N / 10 + N % 10) % 10 //앞에 구한 합의 오른쪽 수
    ③この2つ(①、②)をつなげて新しい数字をつくる.
    2つ追加します.合わせて、10の桁数に10を乗じます.10の桁は①( Nの右端の桁)です.
    N = (N % 10) * 10 + (N / 10 + N % 10) % 10 
    //		①		  + 		②
    4.プロセスを2~3回繰り返し、新しい数が元の数に戻る周期数を求める.
    𘸚は何回繰り返しているのか分からず、𐥊を使用します.
    反復を実行するたびに、変数を追加する必要があります.この変数は宣言時に0に初期化する必要があります.
    while (true) {
    	cnt = cnt + 1;
    	N = (N % 10) * 10 + (N / 10 + N % 10) % 10 
    	//		①		  + 		②
    }
    この場合、%を終了するには、元の数と新しい数が等しいかどうかを比較する必要があります.したがって,初期時には元の数(N)が別の変数に格納される.次に、while문を使用して同じことを確認し、繰り返し文を終了します.
    cin >> N;
    A = N;	//
    while (true) {
    	cnt = cnt + 1;
    	A = (A % 10) * 10 + (A / 10 + A % 10) % 10 
    	//		①		  + 		②
    	if ( N == A ) { //원래 수와 새로운 수가 같은지 비교
        	break;
        }
    }
    コード全体を以下に示します.
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int N, A;
        int cnt = 0;	// 사이클을 계산하는 변수. 초기에 0으로 초기화
    
        cin >> N;		//N을 입력 받는다.
        
        //나중에 if문으로 같은지 비교하기 위해
        //while문 내의 계산을 하기 위한 변수 A에 N의 값을 저장한다.
        A = N;			
    
        while (true) {
            cnt = cnt + 1;	//사이클 수 1 증가
            A = (A % 10) * 10 + (A / 10 + A % 10) % 10; 
            if (N == A) { 	//원래 수와 새로운 수가 같은지 비교
                break;
            }
        }
        cout << cnt; 		//사이클 수를 출력
        
        return 0;
    }

    💡結果の送信💡



    (I/O同期を無効にする必要がないため、この方法は採用されていません.)

    振り返る🤔


  • 初めての试み方がどうしてダメなのか、どうすればいいのか、何日も悩んだ.割らなくても1列に並ぶような気がしますが、方法はよくわかりません.
    このとき、上の文章のように、問題を一つ一つ切り出しました.そのため、想像以上に結論が出やすい.空虚で、喜んで、変な感じがします.だから後の問題も記憶に残る問題になります

  • これはどう書きますか.でも書き終わったら気持ちがいい
  • Reference