# Hướng dẫn giải đề số 1
## Bài 1 : Học - Ăn - Ngủ?
### Đề bài:
Ta có thể hiểu bài toán là cho 3 chỉ số A , B , C sắp xếp lại theo thứ tự tăng dần. Ta có thể nhìn trong những test ví dụ.
### Cách làm
Ta sẽ chia thành các trường hợp như sau:
* Trường hợp 1 : *A* lớn nhất, *B* lớn 2, *C* lớn 3.
* Trường hợp 2 : *A* lớn nhất, *C* lớn 2, *B* lớn 3.
* Trường hợp 3 : *B* lớn nhất, *A* lớn 2, *C* lớn 3.
* Trường hợp 4 : *B* lớn nhất, *C* lớn 2, *A* lớn 3.
* Trường hợp 5 : *C* lớn nhất, *B* lớn 2, *A* lớn 3.
* Trường hợp 6 : *C* lớn nhất, *A* lớn 2, *B* lớn 3.
Ta có 6 trường hợp như trên, việc của ta chỉ là if-else sao cho thỏa mãn các trường hợp trên.
### Code
Ở đây ta sẽ có 2 cách làm:
**Cách 1:**
```c++
#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("LAMGI.INP" , "r" , stdin);
freopen("LAMGI.OUT" , "w" , stdout);
int A , B , C;
cin >> A >> B >> C;
if(A > B && A > C){
cout << "Lam viec, ";
if(B > C)
cout << "Hoc, Ngu";
else cout << "Ngu, Hoc";
}else if(B > A && B > C){
cout << "Hoc, ";
if(A > C)
cout << "Lam viec, Ngu";
else cout << "Ngu, Lam viec";
}else{
cout << "Ngu, ";
if(A > B)
cout << "Lam viec, Hoc";
else cout << "Hoc, Lam viec";
}
}
```
**Cách 2:**
```c++
#include <bits/stdc++.h>
using namespace std;
int main() {
freopen("LAMGI.inp", "r", stdin);
freopen("LAMGI.out", "w", stdout);
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
long long a, b, c;
cin >> a >> b >> c;
if (a > b && a > c && b > c) {
cout << "Lam viec, Hoc, Ngu";
}
else if (a > b && a > c && c > b) {
cout << "Lam viec, Ngu, Hoc";
}
else if (b > a && b > c && a > c) {
cout << "Hoc, Lam viec, Ngu";
}
else if (b > a && b > c && c > a) {
cout << "Hoc, Ngu, Lam viec";
}
else if (c > b && c > a && a > b) {
cout << "Ngu, Lam viec, Hoc";
}
else if (c > b && c > a && b > a) {
cout << "Ngu, Hoc, Lam viec";
}
}
```
Cả 2 cách đều có thể **AC** và đều thực hiện một việc là chia thành 6 trường hợp và in ra kết quả cho mỗi trường hợp khác nhau.
## Bài 2: Đồng Tiền
### Đề bài:
Ở bài toán này, ta sẽ phân tích đề bài như sau. Tom muốn xếp hình tam giác có quy luật là:
* Tầng 1 có 1 đồng tiền
* Tầng 2 có 2 đồng tiền
* ...
* Tầng $k$ có $k$ đồng tiền.
Gọi $S_k$ là tổng số đồng tiền phải sử dụng để xếp hình tam giác có $k$ tầng thì:
$$S_k = 1 + 2 + 3 + .... + (k - 1) + k$$
$$=> S_k = \frac{k * (k + 1)}{2}$$
**Lưu ý:** $\frac{k * (k + 1)}{2}$ là tổng từ $1$ đến $k$.
### Cách làm:
Ta sẽ đi tìm số $k$ lớn nhất có thể sao cho $S_k \le n$. Tức là tìm số $k$ lớn nhất sao cho tổng từ $1$ đến $k$ bé hơn hoặc bằng $n$.
### Code:
Ta đều có thể **AC** bằng cách dùng for hoặc while.
**Cách dùng While:**
```c++
#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("triacoin.inp" , "r" , stdin);
freopen("triacoin.out" , "w" , stdout);
int n;
cin >> n;
int sum = 0 , k = 0;
while(sum + (k + 1) <= n){
k++;
sum = sum + k;
}
cout << k << endl;
}
```
**Cách dùng for:**
```c++
#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("triacoin.inp" , "r" , stdin);
freopen("triacoin.out" , "w" , stdout);
int n;
cin >> n;
int k = 0;
for(int sum = 0 ; ; sum += k){
if(sum + (k + 1) > n) break;
k++;
}
cout << k << endl;
}
```
## Bài 3: Mật khẩu
### Đề bài:
Ở bài này, ta có thể tóm tắt lại bài toán là đếm số xâu có 4 chữ số mà trong đó chỉ có duy nhất 2 chữ số khác nhau (gọi là $x$ và $y$) sao cho cả $x$ và $y$ đều không nằm trong các số $x$ cho trước.
### Cách làm:
Ta có thể duyệt qua từng cặp chữ số $(x , y)$ tương ứng với $2$ chữ số khác nhau, nếu cả 2 đều không nằm trong tập $x$ cho trước thì ta có thể cộng $6$ trường hợp vào với thứ tự như sau:
* $xxyy$
* $xyxy$
* $yxyx$
* $yyxx$
* $xyyx$
* $yxxy$
Ví dụ, với cặp số $(0 , 1)$ thì ta có các số là:
* $0011$
* $0101$
* $1010$
* $1100$
* $0110$
* $1001$
Thì mỗi cặp số như vậy sẽ có $6$ trường hợp thỏa mãn.
### Code:
```c++
#include<bits/stdc++.h>
using namespace std;
int a[10];
int main(){
freopen("matkhau.inp" , "r", stdin);
freopen("matkhau.out" , "w" , stdout);
int numTest;
cin >> numTest;
for(int T = 1 ; T <= numTest ; T++){
int n , kq = 0;
cin >> n;
for(int i = 1 ; i <= n ; i++)
cin >> a[i];
for(int x = 0 ; x <= 9 ; x++){
for(int y = 0 ; y < x ; y++){
bool ok = true;
for(int i = 1 ; i <= n ; i++)
if(x == a[i] || y == a[i]){
ok = false;
break;
}
if(ok == false)
continue;
kq += 6;
}
}
cout << kq << endl;
}
}
```
**Lưu ý:** Bài toán có áp dụng việc có nhiều testcase nhỏ trong 1 test nên ta sẽ đọc **số lượng testcase** trước rồi lặp lại số lần chạy.
**Giải thích code:** Có 2 điểm chính trong code này
* Đầu tiên, với mỗi cặp $(x , y)$ ta sẽ kiểm tra việc có $x$ hoặc $y$ nằm trong tập $x$ hay không bằng cách duyệt qua tất cả các số cho trước rồi so sánh cho $x$ và $y$. Ngoài ra, ta có một biến bool **ok** để kiểm tra $(x , y)$ điều kiện.
* Điều thứ hai, ta sẽ chỉ đếm các cặp $(x , y)$ với $(y < x)$ vì nếu không, tất cả các cặp sẽ bị đếm 2 lần. Ví dụ, nếu ta code như sau:
```c++
for(int x = 0 ; x <= 9 ; x++){
for(int y = 0 ; y <= 9 ; y++){
```
Thì tất cả các cặp sẽ bị lặp lại $2$ lần vì 2 vòng for đếm $(x , y)$ và $(y , x)$.