Basic·Bài B1

cin and cout

Mỗi bài trên trình chấm có chung một dáng: chương trình đọc dữ liệu từ đầu vào chuẩn (standard input), tính toán, rồi in kết quả ra đầu ra chuẩn (standard output). Trình chấm không xem chương trình nghĩ gì: nó đưa vào một đoạn chữ, nhận lại một đoạn chữ rồi so với đáp án. Đọc nhầm thứ tự hai số, in dính hai số vào nhau, hay để kết quả vượt khỏi int đều dẫn tới Sai (Wrong Answer), dù phần tính toán đúng.

Ở bài B0 chương trình chỉ in những thứ có sẵn. Bài này cho nó đọc dữ liệu bằng cin, rồi đi qua những chỗ người mới hay vấp: đọc sai kiểu, đọc chữ, thương và phần dư của số vừa đọc, số thực và số vượt khỏi int.

cin: đọc từng mẩu từ dải chữ

Trình chấm đưa dữ liệu vào chương trình như một dải chữ liền nhau, giống như có người gõ bàn phím mà không ai nhìn màn hình. cin là luồng đầu vào chuẩn, và cin >> x lấy một giá trị từ dải chữ đó bỏ vào biến x. Mũi tên chỉ hướng đi của dữ liệu: cin >> x đi từ cin vào x, ngược với cout << x đi từ x ra cout. Viết ngược thành cin << x hay cout >> x là lỗi biên dịch.

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int a, b, c;
    cin >> a >> b >> c;
    cout << a * b + c << '\n';
}
12 7
30

'\n' (nháy đơn, một ký tự) làm đúng việc của "\n" ở B0, và từ đây ta viết nháy đơn. Gõ nhầm thành '/n' thì g++ chỉ cảnh báo, rồi chương trình in ra một số lạ thay vì xuống dòng.

cin nhớ nó đã đọc tới đâu. Mỗi lần >> bỏ qua mọi khoảng trắng đứng trước (dấu cách, xuống dòng, tab), rồi lấy ra một mẩu chữ liền nhau và đổi thành giá trị theo kiểu của biến. Ở trên a nhận 12, b nhận 7, c nhận 30 dù nó nằm ở dòng khác, và kết quả là 12⋅7+30=11412 \cdot 7 + 30 = 114.

Ô mờ là phần đã đọc hoặc khoảng trắng bị bỏ qua, ô cam là mẩu chữ vừa vào biến. Thử đổi input thành 12abc hay đổi kiểu biến.

Hai hệ quả dùng hằng ngày. Dữ liệu nằm trên một dòng hay nhiều dòng, câu lệnh đọc vẫn y hệt; chỉ thứ tự là quan trọng. Và thứ tự đọc là thứ tự trong đề: đề ghi “một dòng chứa nn và kk” thì đọc cin >> n >> k. Đọc ngược là hoán đổi giá trị hai biến, và bài sai dù mọi phép tính phía sau đều đúng.

Chương trình không có người ngồi trước màn hình, nên đừng in lời nhắc kiểu Nhap a:: mọi chữ thừa trong output đều bị tính là sai. Cũng vì thế, in đúng khuôn của đề: “trên cùng một dòng” thì chèn ' ' giữa các giá trị, “mỗi giá trị một dòng” thì chèn '\n'.

Hỏi nhanh

Dữ liệu vào gồm hai dòng: dòng đầu là 12, dòng sau là 5. Chương trình có int a, b; cin >> b >> a; cout << a - b << '\n';. Nó in ra gì?

Khi chạy thử trên máy mình, cin đọc từ bàn phím, và chương trình đứng yên không phải là treo: nó đang chờ bạn gõ số rồi nhấn Enter. Muốn khỏi gõ lại mỗi lần, ghi dữ liệu mẫu vào tệp input.txt rồi chạy ./main < input.txt (Linux, macOS) hoặc main.exe < input.txt (Command Prompt của Windows; PowerShell không nhận dấu <). Dấu < đưa nội dung tệp vào làm đầu vào chuẩn, đúng như trình chấm làm.

Đến đây ta hiểu được hai dòng đầu main của khung. Mặc định cin và cout làm thêm hai việc để phục vụ người ngồi gõ phím: giữ đúng thứ tự khi chương trình dùng lẫn lệnh đọc ghi kiểu cũ của ngôn ngữ C (scanf, printf), và in hết chữ đang chờ ra màn hình trước mỗi lần đọc để lời nhắc kịp hiện lên. Trình chấm không cần hai việc đó, mà chúng làm chậm: ios::sync_with_stdio(false); tắt việc thứ nhất, cin.tie(0); tắt việc thứ hai. Đề thi viết số lớn bằng lũy thừa của 10: 10610^6 là số 1 theo sau 6 chữ số 0, tức một triệu, còn 10910^9 là một tỷ. Đọc 10610^6 số mà thiếu hai dòng này thì chương trình có thể chậm hơn vài lần, đủ để vượt giới hạn một giây. Đã có dòng thứ nhất thì không dùng lẫn cin, cout với scanf, printf nữa.

Cùng lý do đó, endl in xuống dòng và xả bộ đệm ngay, nên in 10610^6 dòng bằng endl có thể chậm hơn '\n' hàng chục lần. Ngoại lệ duy nhất là bài tương tác (bài 28), nơi phải xả sau mỗi câu hỏi.

Một số kỳ thi đọc ghi qua tệp, tên tệp ghi trong đề. Khi đó thêm hai dòng freopen ở đầu main; chúng nối stdin, stdout vào tệp, còn cin, cout giữ nguyên:

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    freopen("bai.inp", "r", stdin);
    freopen("bai.out", "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);

    int a, b;
    cin >> a >> b;
    cout << a + b << '\n';
}

Chỉ thêm khi đề yêu cầu: gửi lên LQDOJ mà còn freopen thì chương trình đi tìm tệp không tồn tại và không đọc được dữ liệu của trình chấm.

Ví dụHai số đảo chỗ

Đề. Một dòng chứa hai số nguyên aa và bb (−1000≤a,b≤1000-1000 \le a, b \le 1000). In bb rồi đến aa trên cùng một dòng.

Lời giải. Đọc đúng thứ tự đề cho, cin >> a >> b, rồi đảo thứ tự lúc in; không cần đổi giá trị hai biến. Giữa hai số phải có ' ', thiếu nó thì máy in 83 thay vì 8 3. Số âm không cần xử lý gì thêm: cin đọc cả dấu -.

Code đầy đủ
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int a, b;
    cin >> a >> b;
    cout << b << ' ' << a << '\n';
}
3 8

Kiểu của biến: số, ký tự, xâu

Kiểu của biến quyết định cin lấy bao nhiêu chữ. Với biến số, cin không lấy trọn mẩu chữ mà chỉ lấy phần đầu còn đúng dạng số của kiểu đó (có thể mở đầu bằng - hoặc +), và dừng ở ký tự đầu tiên không hợp. Đọc 3.5 vào biến int chỉ lấy được 3; phần .5 nằm lại chờ lần đọc sau. Lần đọc sau gặp dấu chấm, không thể bắt đầu một số nguyên, nên cin rơi vào trạng thái lỗi: biến đang đọc nhận 0, và mọi lệnh cin về sau không làm gì nữa.

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int a = -5, b = -5, c = -5;
    cin >> a >> b >> c;
    cout << a << ' ' << b << ' ' << c << '\n';
}
3.5 7 8

Ba biến được gán sẵn −5-5 để thấy biến nào không được đọc. a lấy 3, b hỏng ở chỗ .5 nên nhận 0, còn c giữ nguyên −5-5: số 7 và 8 không bao giờ được đọc. Số quá lớn so với kiểu cũng làm cin hỏng: đọc 3000000000 vào int cho 2147483647 rồi cũng vào trạng thái lỗi. Nghĩa là đề cho giá trị tới 101010^{10} mà khai báo int thì chương trình sai ngay lúc đọc, trước cả khi có phép tính nào tràn. Thấy những số 0 hay 2147483647 không ngờ tới, hãy in lại các biến ngay sau lệnh cin để xem dữ liệu có vào đúng không.

Hỏi nhanh

Dữ liệu vào là một dòng 3.5 7. Chương trình có int a, b; cin >> a >> b; rồi in a và b cách nhau một dấu cách. Nó in ra gì?

Với chữ, >> vẫn bỏ qua khoảng trắng rồi lấy một mẩu. Biến string (xâu) nhận cả mẩu liền nhau, còn biến char chỉ nhận đúng một ký tự không phải khoảng trắng.

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    string a, b;
    char c;
    cin >> a >> b >> c;
    cout << a << '|' << b << '|' << c << '\n';
}
Nguyen Van An

Ba biến nhận Nguyen, Van và A; chữ n cuối còn nằm đó chưa ai đọc. Vì >> dừng ở khoảng trắng, nó không đọc nổi một dòng có dấu cách bên trong như họ tên hay một câu văn. Để đọc trọn một dòng ta dùng getline(cin, s): nó lấy mọi ký tự tới hết dòng, kể cả dấu cách, và bỏ dấu xuống dòng đi.

Chỗ hay vấp là getline đứng ngay sau một lệnh >>. Lệnh >> đọc xong số thì dừng sát sau số, nên ký tự xuống dòng vẫn nằm trong dải chữ, và getline đọc được ngay một dòng rỗng. Chèn cin.ignore(); vào giữa để bỏ ký tự xuống dòng đó:

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n;
    string name;
    cin >> n;
    cin.ignore();
    getline(cin, name);
    cout << n << ": " << name << '\n';
}
3
Nguyen Van An

Xóa dòng cin.ignore(); thì chương trình chỉ in 3:, vì name nhận dòng rỗng. ignore() chỉ bỏ đúng một ký tự, nên nếu sau số còn dấu cách thừa, hay dòng kết thúc bằng cặp \r\n của Windows, thì nó bỏ chưa đủ. Khi đó viết cin.ignore(1000, '\n');: bỏ đi tới hết dòng chứa số (tối đa 1000 ký tự, thừa sức cho một dòng như vậy).

Ví dụGhép hai chữ số

Đề. Một dòng chứa chữ số hàng chục aa (1≤a≤91 \le a \le 9) và chữ số hàng đơn vị bb (0≤b≤90 \le b \le 9). In số có hai chữ số này.

Lời giải. Số cần in, viết ra giấy, chính là chữ số aa đứng liền trước chữ số bb. Đọc hai chữ số vào hai biến char: mỗi >> bỏ dấu cách rồi lấy đúng một ký tự. In hai ký tự liền nhau, không chèn gì, là ra số cần tìm; vì a≥1a \ge 1 nên không có chữ số 0 thừa ở đầu. Cách số học là đọc vào int rồi in 10 * a + b, đúng kiểu ghép của mục sau.

Code đầy đủ
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    char a, b;
    cin >> a >> b;
    cout << a << b << '\n';
}
4 2

Thương và phần dư: tách, ghép và quay vòng

B0 đã cho biết / giữa hai số nguyên là thương và % là phần dư. Với dữ liệu đọc vào, hai phép này là bộ công cụ chính của các bài nhập môn, vì chúng chia một số thành các phần. Đây chính là phép chia có dư: số bị chia bằng thương nhân số chia cộng số dư, và số dư luôn nhỏ hơn số chia. Viết bằng C++, với n≥0n \ge 0 và k≥1k \ge 1:

n=(n/k)⋅k+n%k,0≤n%k<k.n = (n / k) \cdot k + n \% k, \qquad 0 \le n \% k < k.

Ba cách dùng thường gặp:

  • Đổi đơn vị. Đổi mm phút ra giờ và phút: m / 60 là số giờ trọn, m % 60 là số phút lẻ. Chẳng hạn 200=3⋅60+20200 = 3 \cdot 60 + 20 cho 3 giờ 20 phút.
  • Tách và ghép chữ số. Trong hệ thập phân, n % 10 là chữ số cuối và n / 10 là phần còn lại sau khi bỏ chữ số cuối. Ngược lại, 10 * n + d gắn thêm chữ số dd vào cuối nn.
  • Quay vòng. Đồng hồ chỉ 22 giờ, 30 giờ nữa là mấy giờ? Cộng thẳng ra 52, nhưng một ngày chỉ có 24 giờ: 52 % 24 = 4 là giờ trên đồng hồ, còn 52 / 24 = 2 là số vòng đã đi trọn.

Với số âm, % cho phần dư âm (-7 % 5 ra -2); khi cần phần dư nằm trong [0,k)[0, k), viết (x % k + k) % k.

Ví dụTổng ba chữ số

Đề. Cho số nguyên nn có đúng ba chữ số (100≤n≤999100 \le n \le 999). In tổng ba chữ số của nn.

Lời giải. Mỗi chữ số lấy ra bằng một biểu thức. Chia cho 10 thì số dư là chữ số hàng đơn vị: n % 10. Thương n / 10 là nn bỏ đi chữ số cuối, nên chữ số cuối của thương, n / 10 % 10, là chữ số hàng chục. Chia cho 100 bỏ đi hai chữ số cuối, còn lại chữ số hàng trăm: n / 100. Biểu thức n / 10 % 10 tính từ trái sang phải, tức (n / 10) % 10.

Kéo n: mỗi biểu thức lấy đúng một chữ số.

Với n=307n = 307: 307 / 100 = 3, 307 / 10 = 30 nên 307 / 10 % 10 = 0, 307 % 10 = 7, tổng là 10. Số nhiều chữ số hơn thì lặp lại cặp % 10, / 10 bằng vòng lặp, việc của bài B3.

Code đầy đủ
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;
    cout << n / 100 + n / 10 % 10 + n % 10 << '\n';
}
307

Ví dụVị trí trên vòng

Đề. Một vòng tròn có kk vị trí đánh số từ 00 đến k−1k - 1; sau vị trí k−1k - 1 là vị trí 00. Bắt đầu ở vị trí pp, đi ss bước theo chiều tăng số. In vị trí cuối cùng. Giới hạn: 1≤k≤1001 \le k \le 100, 0≤p<k0 \le p < k, 0≤s≤10000 \le s \le 1000.

Lời giải. Nếu vòng được duỗi thẳng thì ta dừng ở p+sp + s. Mỗi kk bước là đi trọn một vòng và quay về chỗ cũ, nên chỉ phần dư của p+sp + s khi chia cho kk quyết định vị trí: đáp án là (p + s) % k. Với ví dụ k=7k = 7, p=5p = 5, s=4s = 4: 5+4=9=1⋅7+25 + 4 = 9 = 1 \cdot 7 + 2, dừng ở vị trí 2. Đây đúng là bài đồng hồ ở trên với k=24k = 24.

Code đầy đủ
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int k, p, s;
    cin >> k >> p >> s;
    cout << (p + s) % k << '\n';
}
7 5 4

Số thực và số lớn: double, long long

Khi dữ liệu hay kết quả có phần thập phân ta dùng double; cin đọc và cout in nó như số nguyên. Mặc định cout in số thực với 6 chữ số có nghĩa, và số lớn bị đổi sang dạng khoa học. Muốn đúng kk chữ số sau dấu phẩy, thêm fixed << setprecision(k) trước giá trị.

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    double x;
    cin >> x;
    cout << x << '\n';
    cout << fixed << setprecision(2) << x << '\n';
}
1234567.891

fixed << setprecision(k) làm tròn chứ không cắt, và ở lại với cout tới hết chương trình; nó chỉ ảnh hưởng số thực. double chỉ lưu gần đúng, được chừng 15 đến 16 chữ số có nghĩa, nên số nguyên lớn thì giữ bằng long long chứ đừng đưa vào double.

Chỗ sai hay gặp nhất với double là phép chia. Kiểu của một phép tính do các toán hạng quyết định, không do biến nhận kết quả: a / b với hai int là chia nguyên, tính xong rồi mới đổi sang double, lúc đó phần lẻ đã mất.

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int a = 7, b = 2;
    double x = a / b;
    double y = 1.0 * a / b;
    cout << x << ' ' << y << '\n';
}

x nhận 7 / 2 = 3 rồi mới thành 3.0. Ở y, 1.0 * a ra 7.0 trước, nên phép chia sau đó là chia thực; viết (double)a / b cũng được.

Hỏi nhanh

Cho int a = 7, b = 2;. Lệnh cout << (a + b) / 2 * 1.0 << ' ' << 1.0 * (a + b) / 2; in ra gì?

Số nguyên cũng có giới hạn. int chỉ chứa tới 2147483647 (C++ đặt sẵn tên INT_MAX), còn long long tới khoảng 9,2⋅10189{,}2 \cdot 10^{18} (LLONG_MAX, số có 19 chữ số). Khi kết quả một phép tính vượt phạm vi của kiểu, số bị tràn (overflow). Tràn số thì C++ không báo lỗi, cũng không hứa kết quả nào: thường là một số sai, nhiều khi là số âm. Đây là lý do một bài đúng thuật toán vẫn trượt vài test lớn.

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cout << INT_MAX << ' ' << LLONG_MAX << '\n';
    int a = 100000, b = 100000;
    cout << 1LL * a * b << '\n';
}
Mỗi vạch gấp 1000 lần vạch trước. Đổi a, b để thấy lúc nào tích vượt int.

Trước khi gõ code, dùng giới hạn của đề để ước lượng giá trị lớn nhất của dữ liệu, của từng phép tính trung gian và của đáp án. Hai số 10510^5 nhân nhau cho 101010^{10}; ba số 10910^9 cộng nhau cho 3⋅1093 \cdot 10^9; tổng 1+2+⋯+n1 + 2 + \dots + n với n=105n = 10^5 cỡ 5⋅1095 \cdot 10^9. Cả ba đều vượt int dù từng số đọc vào vẫn vừa int. Cái gì có thể vượt khoảng 2⋅1092 \cdot 10^9 thì khai báo long long ngay từ đầu; nghi ngờ thì cứ chọn nó. Biến long long đọc bằng cin và in bằng cout y hệt int.

Quy tắc toán hạng ở trên áp dụng cả ở đây: với a, b là int, câu lệnh long long c = a * b; vẫn sai, vì tích đã tính xong bằng int (và tràn) rồi mới được gán vào c. Cách chữa là hằng 1LL, số 1 kiểu long long, đặt ở đầu chuỗi nhân như trong chương trình trên: phép nhân đầu tiên đã chạy bằng long long, và các phép sau cũng vậy vì chuỗi nhân tính từ trái sang phải. Gọn nhất vẫn là khai báo a, b là long long từ đầu.

Hỏi nhanh

Đã đọc int n; cin >> n; với 0≤n≤1050 \le n \le 10^5 và cần in 1+2+⋯+n1 + 2 + \dots + n, tính bằng công thức n(n+1)/2n(n+1)/2. Đáp án lớn nhất khoảng 5⋅1095 \cdot 10^9. Dòng nào cho kết quả đúng với mọi nn trong giới hạn?

Ví dụTích lớn

Đề. Cho hai số nguyên không âm a,b≤109a, b \le 10^9. In tích a×ba \times b.

Lời giải. Mỗi số còn vừa int, nhưng tích lớn nhất là 101810^{18}: vượt xa 2,1⋅1092{,}1 \cdot 10^9 và vẫn nhỏ hơn 9,2⋅10189{,}2 \cdot 10^{18}, tức vừa long long. Khai báo a, b là long long, đọc, nhân, in. Để int cả hai và nhân thẳng thì ngay test ví dụ 105⋅10510^5 \cdot 10^5 đã in ra một con số sai mà không có cảnh báo nào.

Code đầy đủ
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    long long a, b;
    cin >> a >> b;
    cout << a * b << '\n';
}
100000 100000

Khi đi thi

  • Đọc kỹ định dạng vào và ra trước khi gõ: thứ tự các biến, dấu cách, xuống dòng, đọc ghi bàn phím hay tệp. Không in lời nhắc; chạy ví dụ của đề và so từng ký tự.
  • Trước khi khai báo, ước lượng giá trị lớn nhất của dữ liệu, của các phép tính trung gian và của đáp án; có thể vượt 2⋅1092 \cdot 10^9 thì dùng long long ngay từ đầu, kể cả cho biến đọc vào.
  • Kết quả lạ thì in lại các biến vừa đọc, rồi soát theo thứ tự: đọc sai kiểu hoặc quá phạm vi (số 0 hay 2147483647), phép chia nguyên đang cắt phần thập phân, phép tính trung gian tràn int.

Tóm tắt

  • cin >> a >> b; bỏ qua dấu cách và xuống dòng, đọc theo đúng thứ tự trong đề; không in lời nhắc. Đầu main có ios::sync_with_stdio(false); cin.tie(0);, và xuống dòng bằng '\n' thay cho endl.
  • Với biến số, cin chỉ lấy phần đầu đúng dạng số. Đọc sai kiểu hay quá phạm vi làm cin hỏng: biến nhận 0 hoặc INT_MAX, các lệnh đọc sau bị bỏ qua.
  • char nhận một ký tự, string nhận một từ, getline nhận cả dòng; giữa >> và getline phải bỏ phần còn lại của dòng trước.
  • Phép chia có dư: n = (n / k) * k + n % k, số dư nhỏ hơn số chia. / và % dùng để đổi đơn vị, tách ghép chữ số, quay vòng.
  • int chứa tới 2,1⋅1092{,}1 \cdot 10^9, long long tới 9,2⋅10189{,}2 \cdot 10^{18}; kiểu phép tính do toán hạng quyết định nên viết 1LL * a * b và 1.0 * a / b.

Bài tập

1
Nhắc lại một sốcanucbasic1l01 · Basic 1 · HọcĐọc vào một biến int rồi in lại; mũi tên của cin và cout chỉ hai chiều ngược nhau.
LQDOJ
2
Số tiếp theocanucbasic1e01 · Basic 1 · LuyệnSố liền sau là n+1n + 1, kể cả khi nn âm.
LQDOJ
3
Tổng hai sốcanucbasic1l03 · Basic 1 · HọcTính a + b ngay trong câu lệnh in; số âm vẫn cộng bình thường.
LQDOJ
4
Tổng ba sốcanucbasic1e02 · Basic 1 · LuyệnBa biến, một chuỗi cin >> a >> b >> c; dữ liệu nằm trên một dòng hay nhiều dòng đều đọc được.
LQDOJ
5
Hiệu và tíchcanucbasic1l04 · Basic 1 · HọcHai kết quả nằm trên hai dòng khác nhau, nên giữa chúng cần '\n'.
LQDOJ
6
Hình chữ nhậtcanucbasic1l05 · Basic 1 · HọcChu vi 2(a+b)2(a + b) và diện tích abab in trên cùng một dòng, cách nhau một dấu cách.
LQDOJ
7
Diện tích hình hộpcanucbasic1e09 · Basic 1 · LuyệnSáu mặt gồm ba cặp mặt bằng nhau: 2(ab+bc+ca)2(ab + bc + ca).
LQDOJ
8
Chữ số hàng đơn vịcanucbasic1l07 · Basic 1 · HọcChia nn cho 10 theo n=q⋅10+rn = q \cdot 10 + r: phần dư rr cho biết điều gì về chữ số của nn?
LQDOJ
9
Chia kẹocanucbasic1l06 · Basic 1 · HọcMỗi bạn nhận thương, số kẹo thừa là phần dư; thử với n=0n = 0.
LQDOJ
10
Đổi phútcanucbasic1l08 · Basic 1 · HọcMột giờ có 60 phút: thương là số giờ trọn, phần dư là số phút còn lại.
LQDOJ
11
Tiền thừacanucbasic1e05 · Basic 1 · LuyệnSố tiền phải trả là n⋅pn \cdot p; tiền thừa là hiệu của số tiền đưa và số này.
LQDOJ
12
Tiết kiệm đềucanucbasic1e10 · Basic 1 · LuyệnSố tiền là a+b⋅da + b \cdot d; tính xem b⋅db \cdot d lớn nhất bằng bao nhiêu rồi chọn kiểu dữ liệu.
LQDOJ
13
Đổi giâycanucbasic1e03 · Basic 1 · LuyệnMột giờ có 3600 giây: lấy thương cho giờ, rồi chia tiếp phần dư cho 60 để được phút và giây.
LQDOJ
14
Đảo số ba chữ sốcanucbasic1e04 · Basic 1 · LuyệnTách ba chữ số như ví dụ Tổng ba chữ số rồi ghép theo thứ tự ngược; số 0 ở đầu tự mất khi ghép thành một số.
LQDOJ
15
Chia nhómcanucbasic1e08 · Basic 1 · LuyệnChia nguyên làm tròn xuống mà đề cần làm tròn lên; tìm một số cộng vào nn trước khi chia để trường hợp chia hết và không chia hết dùng chung một công thức.
LQDOJ

Đọc thêm

  • Introduction to iostream: cout, cin, and endlLearn C++Giảng chậm về bộ đệm đầu vào và đầu ra, cách >> lấy từng mẩu dữ liệu, và chuyện gì xảy ra khi dữ liệu nhập sai.
  • Basic Input/Outputcplusplus.comcout, cin, getline và stringstream qua những ví dụ ngắn.
  • std::basic_istream::operator>>cppreferenceTra cứu chính xác việc >> đọc số: bỏ khoảng trắng, đọc lỗi cho giá trị 0, quá phạm vi cho giá trị lớn nhất cùng trạng thái lỗi.
  • I/O performance with cin and cout in C++Kattis HelpBa việc làm cin, cout nhanh hơn (đồng bộ với stdio, tie, endl) và lý do của từng việc.
  • IO OptimizationOI WikiTừ hai dòng tăng tốc tới tự viết hàm đọc bằng getchar và fread, kèm cách bộ đệm được xả.
  • Input & OutputUSACO GuideBài nộp thật đầu tiên trên CSES (Weird Algorithm, cần số nguyên 64 bit) và phần đọc ghi qua tệp của các đề USACO cũ.