[伯俊]第一段階I/Oと四則演算


https://www.acmicpc.net/step/1
これは残りの6つの問題に対する解答過程で、基本的な11つの問題を除いて.

10171番猫


https://www.acmicpc.net/problem/10171
#include <iostream>
using namespace std;

int main() {
	cout << "\\    /\\" << endl;
	cout << " )  ( \')" << endl;
	cout << "(  /  )" << endl;
	cout << " \\(__)|" << endl;

	return 0;
}

/*
	\    /\
	 )  ( ')
	(  /  )
	 \(__)|
*/

10172号


https://www.acmicpc.net/problem/10172
#include <iostream>
using namespace std;

int main() {
	cout << "|\\_/|" << endl;
	cout << "|q p|   /}" << endl;
	cout << "( 0 )\"\"\"\\" << endl;
	cout << "|\"^\"`    |" << endl;
	cout << "||_/=\\\\__|" << endl;

	return 0;
}

/*

|\_/|
|q p|   /}
( 0 )"""\
|"^"`    |
||_/=\\__|

*/
  • `(逆引用符)および/(正スラッシュ)は特殊文字ではないので、直接出力します.
  • "(一重引用符)、"(二重引用符)、(反スラッシュ)のような特殊文字は、その文字自体を出力するために前に反スラッシュを付けなければならない.これにより、反スラッシュは文字の特殊機能を除去することができる.
  • 1008 A/B


    https://www.acmicpc.net/problem/1008
  • 実際正解と出力値の絶対誤差または相対誤差が10^(-9)以下であれば正解?
    小数点以下の桁数は「9桁以上」でOK!
  • 精度関数は、少数の整数部と小数部を含むビット数を決定する.
  • でfixedを使用する場合、整数を除いては「小数点以下の桁数」しか指定できません.
  • #include <iostream>
    using namespace std;
    
    int main()
    {
        int a = 10;
        int b = 3;
    
        cout << fixed;
        cout.precision(9);
        cout << a / (double)b << endl;
        // 3.333333333 (소수점 아래부터 9자리)
    
        cout.unsetf(ios::fixed);
        cout << a / (double)b;
        // 3.33333333 (정수부, 소수부 모두 포함해서 9자리)
    }

    1008番の答え(次のコードは小数点以下の9桁しか出力されませんが、より多くの桁を増やすことができます)。

    #include <iostream>
    using namespace std;
    
    int main()
    {
        int a, b;
        cin >> a >> b;
    
    	// C++의 iostream 스타일
        cout << fixed;
        cout.precision(9);
        cout << a / (double)b << endl;
    
    	// C의 stdio.h 스타일
        printf("%.9lf\n", a / (double)b);
    
        return 0;
    }
    分母が0になったら?無限大を表すinf(無限大)が出力されます.

    10869号四則演算


    https://www.acmicpc.net/problem/10869
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int a, b;
        cin >> a >> b;
    
        cout << a + b << endl;
        cout << a - b << endl;
        cout << a * b << endl;
        cout << a / b << endl; // 몫 (a,b 모두 int형이므로 소수점 버림)
        cout << a % b << endl; // 나머지
    
    
        return 0;
    }

    10430回余剰演算


    https://www.acmicpc.net/problem/10430
    (A+B)%Cは(A%C)+(B%C)%Cと同じですか?
    (A×B)%Cは(A%C)× (B%C)は%Cと同じですか?
    3つの数A,B,Cが与えられた場合は,上記の4つの値を求めるプログラムを作成する.
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int A, B, C;
        cin >> A >> B >> C; // 5 8 4
    
        cout << (A + B) % C << endl; // 13 % 4 == 1
        cout << ((A % C) + (B % C)) % C << endl; // 1 % 4 == 1
        cout << (A * B) % C << endl; // 40 % 4 == 0
        cout << ((A % C) * (B % C)) % C << endl; // 0 % 4 == 0
    
        return 0;
    }
    など、結果だけを確認するのではなく、次の式がなぜ成り立っているのかを簡単に証明しましょう.
  • (A+B)%C == ((A%C) + (B%C))%C
  • (A*B)%C == ((A%C) * (B%C))%C
    下図のように、残りの演算は当たり前の結果になりますが、目で見るだけでは、なぜか理解できません!

  • ソース:https://st-lab.tistory.com/214

  • ブール1:%と+では、%の優先度が高く、カッコは必要ありませんが、%と*の優先度は同じなので、カッコを使用する必要があります.
    cf)演算子優先度:https://dojang.io/mod/page/view.php?id=188

  • 副演2:の違いは?
    https://sumini.dev/til/004-cpp-input-output/
  • iostreamは、I/Oを実行するためのすべてのC++ストリームを含むヘッダファイルです.
    printfはcoutより速いため、主に特殊な場合に用いられ、通常C++でcoutが用いられる.これは「cstdio」と「iostream」と同じですが、両方が使用可能であれば、iostreamを使用するとより安全になります.具体的な理由は次のとおりです.
  • type-safe:iostreamには%d、%fなどのフォーマット指定子がなく、変数名を直接使用するため、コンパイラは静的にオブジェクトタイプを決定することができます.
    ただし、cstdioは変数値をフォーマット指定子(例えば%d、%f)に渡す方式であるため、コンパイラは入力/出力の変数がどのようなタイプなのか分からず、実行時にのみ動的(dynamic)に知ることができる.そのためiostreamはよりtype-安全です.
  • エラー:cstdioでは、入力/出力オブジェクトのタイプがフォーマット指定子と一致する必要がありますが、iostreamではありません.そのためiostreamでエラーが発生する可能性は低い.
  • 拡張性:iostreamは、既存のコードを変更することなく、カスタムタイプを入力/出力できます.
  • 継承性:iostreamメカニズムはstd::ostreamまたはstd:istreamのような真のクラスから作成され、cstdioのFILE*とは異なり継承できます.したがって、ユーザはストリームを直接定義して起動することができる.cstdioのprintf関数は、パラメータタイプをチェックしない可変パラメータ関数であり、他のタイプに再ロードすることもできません.
  • 2588回乗算


    https://www.acmicpc.net/problem/2588

    6番は入力した2つの整数を乗せればいいのですが、3、4、5番は2番目の整数を桁数で分けて、1番目の整数とそれぞれ乗せればいいのです.では、3桁の整数を1桁に分離するにはどうすればいいのでしょうか.
    方法1:除算演算(商、剰余)
    方法2:文字配列、atoi関数の使用
    メソッド3:string stoi関数を使用

    方法除算演算

    #include <iostream>
    using namespace std;
    
    int main() {
    	int a, b;
    	cin >> a >> b;
    
    	cout << a * (b % 10) << "\n";
    	cout << a * ((b % 100) / 10) << "\n";
    	cout << a * (b / 100) << "\n";
    	cout << a * b << "\n";
    
    	return 0;
    }
    など、改行用std::endと「n」の違いは何ですか?
    ソース:https://cocoon1787.tistory.com/135
    // MANIPULATORS
    template <class _Elem, class _Traits>
    basic_ostream<_Elem, _Traits>& __CLRCALL_OR_CDECL endl(
        basic_ostream<_Elem, _Traits>& _Ostr) { // insert newline and flush stream
        _Ostr.put(_Ostr.widen('\n'));
        _Ostr.flush();
        return _Ostr;
    }
    ENDは常にnewlineと出力バッファのflush関数を同時に実行するため、「n」のみを出力するよりも時間がかかります.次は実際のテスト結果です.
    #include<iostream>
    #include<time.h>
    using namespace std;
    
    int main()
    {
    	clock_t start, end; // clock_t는 long형 4바이트
    	long time1, time2, time3;
    
    	// cout, endl
    	start = clock();
    	for (int i = 0; i < 1000; i++)
    		cout << i << endl;
    	end = clock();
    	time1 = end - start;
    
    	// cout , \n
    	start = clock();
    	for (int i = 0; i < 1000; i++)
    		cout << i << "\n";
    	end = clock();
    	time2 = end - start;
    
    	// printf, \n
    	start = clock();
    	for (int i = 0; i < 1000; i++)
    		printf("%d\n", i);
    	end = clock();
    	time3 = end - start;
    
    	printf("\n\n");
    
    	// 출력하는 데 걸린 시간 비교
    	cout << "cout << i << endl : " << time1 << "ms" << endl;
    	cout << "cout << i << \"\\n\" : " << time2 << "ms" << endl;
    	cout << "printf(\"%d\\n\", i) : " << time3 << "ms" << endl;
    
    	return 0;
    }

    🤔 しかし、flush関数「出力バッファをクリア」とはどういう意味ですか?
    注意:https://yechoi.tistory.com/48

    方法文字配列、atoi関数の使用

  • の3ビットの整数を文字配列として受信するには、最後の空の文字を含む4バイトが必要です.
  • 文字は内部でASKIDコードに従って整数に変換され、文字「0」は10進数48に相当する.
  • atoi関数は文字列を整数に変換します.(失敗した場合は0)
    int atoi(char const* String);
  • #include <iostream>
    using namespace std;
    
    int main() {
    	int a;
    	char b[4];
    	cin >> a >> b;
    
    	cout << a * (b[2] - 48) << "\n"; // 일의 자리수
    	cout << a * (b[1] - 48) << "\n"; // 십의 자리수
    	cout << a * (b[0] - 48) << "\n"; // 백의 자리수
    	cout << a * atoi(b) << "\n"; // 문자 배열을 정수로 변환해주는 atoi 함수
    
    	return 0;
    } 

    方法string、stoi関数の使用

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
    	int a;
    	string b;
    	cin >> a >> b;
    
    	cout << a * (b[2] - 48) << "\n"; // 일의 자리수
    	cout << a * (b[1] - 48) << "\n"; // 십의 자리수
    	cout << a * (b[0] - 48) << "\n"; // 백의 자리수
    	cout << a * stoi(b) << "\n"; // 문자열을 정수로 변환해주는 stoi 함수
    
    	return 0;
    }