Chuyển tới nội dung chính

Đề Lý thuyết số 1: Đề thi 2024 - 2025

Câu 1.​

Cho đoạn chương trình sau:

#include <iostream>
using namespace std;
int main() {
int a = 15 % 6;
int b = (a++) + 2;
int c = (a > b ? a - b : b - a);
int d = 2 + (c >= 3);
cout << a << b << c << d;
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là 4 5 1 2

Giải thích:​

Câu lệnh: int a = 15 % 6;

  • a=15%6=3a = 15 \% 6 = 3

Câu lệnh: int b = (a++) + 2;

  • Xét câu lệnh này có xuất hiện toán tử tăng sau (a++a++) nên:
  • b=(a++)+2b = (a++) + 2 ⇔\Leftrightarrow b=a+2b = a + 2 và a++a++
  • ⇒b=3+2=5\Rightarrow b = 3 + 2 = 5
  • a++a++ ⇒a=4\Rightarrow a = 4

Câu lệnh: int c = (a > b ? a - b : b - a);

  • Thay giá trị vào: (4>5?4−5:5−4)(4 > 5 ? 4 - 5 : 5 - 4)
  • Vì 4>54 > 5 là Sai, biểu thức trả về giá trị sau dấu : là 5−4=15 - 4 = 1
  • Vậy c=1c = 1

Câu lệnh: int d = 2 + (c >= 3);

  • Biểu thức so sánh (c>=3)(c >= 3) hay (1≥3)(1 \ge 3) trả về giá trị False (trong C++ tương ứng với số 0).
  • Vậy d=2+0=2d = 2 + 0 = 2

Câu 2.​

Cho một đoạn chương trình sau:

#include <iostream>
using namespace std;
int main() {
int x = 1, y = 0;
if (!y || (x++))
cout << x - y;
else
cout << y - x;
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là: 1

Giải thích:​

Xét điều kiện trong câu lệnh if (!y || (x++)):

  • Ban đầu ta có y=0y = 0, do đó biểu thức !y!y (phủ định của 0) sẽ tương đương với !false, kết quả là 1.
  • Trong toán tử logic OR (||), nếu điều kiện thứ nhất đã đúng (true) thì toàn bộ mệnh đề được kết luận là đúng không cần xét điều kiện thứ hai.

Do đó, giá trị của biến xx vẫn giữ nguyên là 1. Vì điều kiện if đúng, chương trình thực hiện lệnh: cout << x - y;.

Với x=1x = 1 và y=0y = 0, phép tính sẽ là: 1−0=11 - 0 = 1.

Câu 3.​

Cho một đoạn chương trình sau:

#include <iostream>
using namespace std;
int main() {
int x = 13, y = 4;
switch (x % y) {
case 0: y--;
case 1: x -= y;
case 2: y /= 2;
case 3: x %= 3;
}
cout << y << x;
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là 20

Giải thích:​

Khởi tạo: x=13,y=4x = 13, y = 4.

Biểu thức switch: x%y=13(mod4)=1x \% y = 13 \pmod 4 = 1.

Chương trình sẽ nhảy vào case 1:

  • x−=yx -= y ⇒x=13−4=9\Rightarrow x = 13 - 4 = 9.

Vì không có lệnh break nên chương trình tiếp tục vào các case tiếp theo: Nhảy vào case 2:

  • y/=2y /= 2 ⇒y=4/2=2\Rightarrow y = 4 / 2 = 2.

Tương tự như case 1, không có break nên tiếp tục nhảy vào case 3:

  • x%=3x \%= 3 ⇒x=9(mod3)=0\Rightarrow x = 9 \pmod 3 = 0.

Kết quả cuối cùng:

  • Giá trị hiện tại là y=2y = 2 và x=0x = 0.
  • Lệnh cout << y << x; sẽ in ra màn hình giá trị của yy trước, sau đó đến xx.

Câu 4.​

Cho lưu đồ sau, với N=42367N = 42367

Logo

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là 10

Giải thích:​

Dựa vào lưu đồ, thuật toán thực hiện việc duyệt qua từng chữ số của NN và biến SS sẽ cộng dồn giá trị của chữ số đó nếu nó là số lẻ.

Khởi tạo: S=0,N=42367S = 0, N = 42367.

Bước 1: N=42367N = 42367 (là số lẻ vì N(mod2)=1N \pmod 2 = 1)

  • S=S+(N(mod10))=0+7=7S = S + (N \pmod {10}) = 0 + 7 = 7
  • N=N/10=4236N = N / 10 = 4236

Bước 2: N=4236N = 4236 (là số chẵn, điều kiện N(mod2)=1N \pmod 2 = 1 là Sai)

  • SS không đổi (S=7S = 7)
  • N=N/10=423N = N / 10 = 423

Bước 3: N=423N = 423 (là số lẻ)

  • S=S+(N(mod10))=7+3=10S = S + (N \pmod {10}) = 7 + 3 = 10
  • N=N/10=42N = N / 10 = 42

Bước 4: N=42N = 42 (là số chẵn)

  • SS không đổi (S=10S = 10)
  • N=N/10=4N = N / 10 = 4

Bước 5: N=4N = 4 (là số chẵn)

  • SS không đổi (S=10S = 10)
  • N=N/10=0N = N / 10 = 0

Kết thúc: N=0N = 0 khiến điều kiện lặp (N>0)(N > 0) bị Sai. Chương trình thoát lặp và in giá trị của SS=10.

Câu 5.​

Cho một đoạn chương trình sau:

#include <iostream>
using namespace std;
int S = 0, i = 5;
int main() {
while (i > 0 && S < 10) {
S += i;
i++;
}
cout << i << S;
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là 711

Giải thích:​

Dựa vào vòng lặp while với điều kiện (i>0 vaˋ S<10)(i > 0 \text{ và } S < 10):

Khởi tạo: S=0,i=5S = 0, i = 5.

Lần 1: Điều kiện (5>0 vaˋ 0<10)(5 > 0 \text{ và } 0 < 10) là Đúng.

  • S+=5⇒S=5S += 5 \Rightarrow S = 5
  • i++⇒i=6i++ \Rightarrow i = 6

Lần 2: Điều kiện (6>0 vaˋ 5<10)(6 > 0 \text{ và } 5 < 10) là Đúng.

  • S+=6⇒S=11S += 6 \Rightarrow S = 11
  • i++⇒i=7i++ \Rightarrow i = 7

Lúc này S=11S = 11, điều kiện (S<10)(S < 10) trở thành Sai.

Thoát vòng lặp.Chương trình thực hiện lệnh cout << i << S;. In ra giá trị i=7i=7 và S=11S=11 viết liền nhau là 711.

Câu 6.​

Cho một đoạn chương trình sau:

#include <iostream>
using namespace std;
int main() {
int n = 3085, t = 0;
do {
n = n / 10;
if (n % 10 % 2) continue;
t += n % 10;
} while (n);
cout << t;
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là 8

Giải thích:​

Dựa vào vòng lặp do-while:

Khởi tạo: n=3085,t=0n = 3085, t = 0.

Lần 1:

  • n=3085/10=308n = 3085 / 10 = 308
  • Xét điều kiện if (n % 10 % 2) ⇒(308(mod10)(mod2))⇒(8(mod2))=0\Rightarrow (308 \pmod{10} \pmod 2) \Rightarrow (8 \pmod 2) = 0 (False).
  • Nhảy đến lệnh tiếp theo: t+=n(mod10)⇒t+=8⇒t=8t += n \pmod{10} \Rightarrow t += 8 \Rightarrow t = 8.

Lần 2:

  • n=308/10=30n = 308 / 10 = 30
  • Xét điều kiện if ⇒(30(mod10)(mod2))⇒(0(mod2))=0\Rightarrow (30 \pmod{10} \pmod 2) \Rightarrow (0 \pmod 2) = 0 (False).
  • Nhảy đến lệnh tiếp theo: t+=n(mod10)⇒t+=0⇒t=8t += n \pmod{10} \Rightarrow t += 0 \Rightarrow t = 8.

Lần 3:

  • n=30/10=3n = 30 / 10 = 3
  • Xét điều kiện if ⇒(3(mod10)(mod2))⇒(3(mod2))=1\Rightarrow (3 \pmod{10} \pmod 2) \Rightarrow (3 \pmod 2) = 1 (True).
  • Thực hiện lệnh continue (bỏ qua các lệnh còn lại trong vòng lặp, quay lại kiểm tra điều kiện while).

Lần 4:

  • n=3/10=0n = 3 / 10 = 0
  • Xét điều kiện if ⇒(0(mod10)(mod2))⇒0\Rightarrow (0 \pmod{10} \pmod 2) \Rightarrow 0 (False).
  • Thực hiện lệnh tiếp theo: t+=n(mod10)⇒t+=0⇒t=8t += n \pmod{10} \Rightarrow t += 0 \Rightarrow t = 8.

Kết thúc: n=0n = 0 nên điều kiện vòng lặp while(n) bị sai và thoát.

Câu 7.​

Cho một đoạn chương trình sau:

#include <iostream>
using namespace std;

void fun(int &a, int b) {
a = --b; // a=4, b=4
b %= 2; // b=0
}

int main() {
int a = 5, b = 10;
fun(b, a);
cout << a << b;
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là 54

Giải thích:​

Phân tích hàm fun(int &a, int b):

  • Tham số thứ nhất int &a là tham chiếu (reference).
  • Tham số thứ hai int b là tham trị (value).

Khi gọi hàm fun(b, a) trong main:

  • Biến b của main (giá trị 10) được truyền vào tham số &a (tham chiếu). Do đó, mọi sự thay đổi trên a trong hàm fun thực chất là thay đổi biến b của main.
  • Biến a của main (giá trị 5) được truyền vào tham số b (tham trị). Giá trị được copy sang một vùng nhớ khác, nên thay đổi b trong hàm fun không ảnh hưởng đến a của main.

Trong hàm fun thực thi:

Ban đầu: &a (chiếu tới b_main = 10), b_fun = 5.

Câu lệnh a = --b;:

  • --b (tiền tố): giảm b_fun xuống 1 đơn vị ⇒b=4\Rightarrow b = 4.
  • Gán giá trị này cho a: a = 4. Vì a là tham chiếu của b_main nên lúc này b_main = 4.

Câu lệnhb %= 2;: làm cho b_fun = 4 % 2 = 0 (không ảnh hưởng đến main).

Khi quay lại hàm main:

  • Biến a của main vẫn giữ nguyên giá trị ban đầu là 5.
  • Biến b của main đã bị thay đổi thông qua tham chiếu trong hàm fun, giá trị mới là 4.
  • Lệnh cout << a << b; in ra hai giá trị viết liền nhau là 54.

Câu 8.​

Cho một đoạn chương trình sau:

#include <iostream>
using namespace std;
int fun(int n) {
if (n == 0) return 0;
return ((n % 10 % 7) ? 1 : n % 10) + fun(n / 10);
}
int main() {
cout << fun(731);
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là 9

Giải thích:​

Trong quá trình gọi hàm đệ quy fun(n), ta có câu lệnh chủ chốt: return ((n % 10 % 7) ? 1 : n % 10) + fun(n / 10);

Ý nghĩa:

  • Nếu chữ số cuối cùng (n%10n \% 10) chia cho 7 có dư (không chia hết cho 7), biểu thức điều kiện trả về 1.
  • Nếu chữ số cuối cùng chia hết cho 7 (dư 0), biểu thức điều kiện trả về chính chữ số đó (n%10n \% 10).
  • Sau đó cộng dồn với giá trị của hàm gọi đệ quy cho các chữ số phía trước (fun(n / 10)).

Quá trình thực thi cụ thể:

fun(731):

  • Chữ số cuối là 1. 1(mod7)=11 \pmod 7 = 1 (khác 0) ⇒\Rightarrow Trả về 1.
  • Biểu thức: 1+fun(73)1 + \text{fun}(73)

fun(73):

  • Chữ số cuối là 3. 3(mod7)=33 \pmod 7 = 3 (khác 0) ⇒\Rightarrow Trả về 1.
  • Biểu thức: 1+fun(7)1 + \text{fun}(7)

fun(7):

  • Chữ số cuối là 7. 7(mod7)=07 \pmod 7 = 0 (chia hết cho 7) ⇒\Rightarrow Trả về chính nó là 7.
  • Biểu thức: 7+fun(0)7 + \text{fun}(0)

fun(0):

  • Thỏa mãn điều kiện dừng if (n == 0), trả về 0.

Tính ngược lại:

  • fun(0)=0\text{fun}(0) = 0
  • fun(7)=7+0=7\text{fun}(7) = 7 + 0 = 7
  • fun(73)=1+7=8\text{fun}(73) = 1 + 7 = 8
  • fun(731)=1+8=9\text{fun}(731) = 1 + 8 = 9

Câu 9.​

Cho một đoạn chương trình sau:

#include <iostream>
using namespace std;

void fun(int a[], int &n, int k) {
for (int i = k; i < n - 1; i++)
a[i] = a[i + 1];
n--;
}

int out(int a[], int n) {
int S = 0;
for (int i = 0; i < n; i++)
S += a[i];
return S;
}

int main() {
int a[5] = {1, 2, 7, 0, 3};
int n = 5;
fun(a, n, 3);
cout << out(a, n);
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là 13

Giải thích:​

Chương trình thực hiện việc xóa một phần tử tại vị trí kk trong mảng và tính tổng các phần tử còn lại.

Khởi tạo: Mảng a={1,2,7,0,3}a = \{1, 2, 7, 0, 3\} với n=5n = 5.

Gọi hàm fun(a, n, 3) (Xóa phần tử tại chỉ số k=3k=3):

  • Tham số &n được truyền theo tham chiếu, nên giá trị nn trong main sẽ bị thay đổi trực tiếp.

Vòng lặp for (i=3i=3):

  • Khi i=3i = 3: a[3]=a[4]⇒a[3]=3a[3] = a[4] \Rightarrow a[3] = 3.
  • Mảng lúc này trở thành: {1,2,7,3,3}\{1, 2, 7, 3, 3\}.

Kết thúc vòng lặp: Thực hiện n-- ⇒n=4\Rightarrow n = 4.

Gọi hàm out(a, n) với n=4n=4:

  • Hàm này tính tổng SS các phần tử từ a[0]a[0] đến a[3]a[3].
  • S=a[0]+a[1]+a[2]+a[3]S = a[0] + a[1] + a[2] + a[3]
  • S=1+2+7+3=13S = 1 + 2 + 7 + 3 = 13.

Câu 10.​

Cho một đoạn chương trình sau:

#include <iostream>
using namespace std;

int fun(int a[][3], int n) {
int t = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (a[i][j])
t++;
return t;
}

int main() {
int a[3][3] = {{1, 0, 3}, {0, 3, 1}, {3, 2, 0}};
cout << fun(a, 3);
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là 6

Giải thích:​

Mục đích của hàm fun:

Hàm này sử dụng hai vòng lặp lồng nhau để duyệt qua tất cả các phần tử của mảng 2 chiều. Điều kiện if (a[i][j]) tương đương với việc kiểm tra xem giá trị tại ô đó có khác 0 hay không. Nếu khác 0, biến đếm t sẽ tăng lên 1.

Phân tích mảng a[3][3]:

  • Hàng 0: {1, 0, 3} →\rightarrow Có 2 phần tử khác 0 (là 1 và 3).
  • Hàng 1: {0, 3, 1} →\rightarrow Có 2 phần tử khác 0 (là 3 và 1).
  • Hàng 2: {3, 2, 0} →\rightarrow Có 2 phần tử khác 0 (là 3 và 2).

Tổng cộng có 2+2+2=62 + 2 + 2 = 6 phần tử thỏa mãn điều kiện khác 0.

Câu 11.​

Cho chương trình sau:

#include <iostream>
using namespace std;

void f(int &p1, int p2)
{
p1++;
p2++;
}

int main()
{
int x1 = 1;
int x2 = 1;
f(x1, x2);
cout << "x1 is " << x1 << " x2 is " << x2;

return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Kết quả của chương trình này là: x1 is 2 x2 is 1

Giải thích:​

Hàm f(int &p1, int p2):

  • int &p1: Là tham số truyền theo tham chiếu. Khi hàm thực hiện p1++, nó tác động trực tiếp lên vùng nhớ của biến được truyền vào (là x1).
  • int p2: Là tham số truyền theo tham trị. Khi gọi hàm, một bản sao của giá trị được tạo ra. Lệnh p2++ chỉ làm tăng giá trị của bản sao này bên trong hàm, không ảnh hưởng đến biến gốc (x2).

Quá trình thực thi trong main:

  • Khởi tạo x1=1,x2=1x1 = 1, x2 = 1.
  • Gọi hàm f(x1, x2):
    • p1 trỏ đến x1 ⇒\Rightarrow x1 tăng lên thành 2.
    • p2 nhận giá trị copy của x2 (là 1) ⇒\Rightarrow p2 tăng lên 2, nhưng x2 vẫn là 1.

Câu 12.​

Cho một đoạn chương trình sau:

#include <iostream>
using namespace std;
int main() {
int n = 10;
int *p1 = &n;
int *p2 = p1;
p1 = new int(50);
n--;
cout << (*p1) << (*p2);
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là 509

Giải thích:​

Chương trình thực hiện các thao tác quản lý bộ nhớ và con trỏ như sau:

Khởi tạo ban đầu:

  • int n = 10;: Biến n mang giá trị 10.
  • int *p1 = &n;: Con trỏ p1 trỏ đến địa chỉ của biến n.
  • int *p2 = p1;: Con trỏ p2 cũng trỏ đến địa chỉ mà p1 đang trỏ (tức là cùng trỏ vào biến n).

Thay đổi địa chỉ con trỏ:

  • p1 = new int(50);: Lệnh new cấp phát một vùng nhớ mới trên Heap mang giá trị 50 và cho p1 trỏ vào đó.

  • Lưu ý: Lúc này p1 không còn trỏ vào n nữa, nhưng p2 thì vẫn trỏ vào biến n ở vùng nhớ Stack.

Thay đổi giá trị biến:

  • n--;: Giá trị của biến n giảm xuống 1 (từ 10 còn 9).
  • Vì p2 đang trỏ vào n nên *p2 lúc này sẽ bằng 9.

Kết quả in ra:

  • *p1: Giá trị tại vùng nhớ mới là 50.
  • *p2: Giá trị của biến n sau khi giảm là 9.

Câu 13.​

Cho một đoạn chương trình sau:

#include <iostream>
using namespace std;

void fun(int* a, int* b) {
int temp = *b;
*b = *a;
*a = temp;
}

int main() {
int* p1 = new int(5);
int* p2 = new int(7);
fun(p1, p2);
cout << *p1 << " " << *p2;
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là 7 5

Giải thích:​

Chương trình sử dụng hàm để hoán đổi (swap) giá trị của hai vùng nhớ mà con trỏ đang trỏ tới:

Khởi tạo:

  • p1 trỏ tới vùng nhớ có giá trị 5.
  • p2 trỏ tới vùng nhớ có giá trị 7.

Gọi hàm fun(p1, p2):

  • Tham số a nhận địa chỉ của p1, tham số b nhận địa chỉ của p2.
  • int temp = *b;: Biến tạm temp lưu giá trị tại địa chỉ b (giá trị là 7).
  • *b = *a;: Gán giá trị tại địa chỉ a (là 5) vào địa chỉ b. Lúc này vùng nhớ của p2 mang giá trị 5.
  • *a = temp;: Gán giá trị của temp (là 7) vào địa chỉ a. Lúc này vùng nhớ của p1 mang giá trị 7.

Kết quả:

  • Sau khi hàm kết thúc, giá trị tại hai vùng nhớ đã được tráo đổi cho nhau.
  • Lệnh cout << *p1 << " " << *p2; sẽ in ra giá trị mới là 7 5.

Câu 14.​

Cho một đoạn chương trình sau:

#include <iostream>
using namespace std;
struct Account {
int id;
char type;
};

int main() {
Account Arr[3] = {{10, 'A'}, {20, 'B'}, {30, 'C'}};
Account* x = Arr;
Account* y = x + 2;
cout << x->type;
cout << (y->id) - (x->id);
return 0;
}

Sau khi thực hiện chương trình, kết quả in ra màn hình là gì?

Lời giải:​

Sau khi thực hiện chương trình, kết quả in ra màn hình là A20

Giải thích:​

Chương trình thực hiện thao tác trên mảng các cấu trúc thông qua con trỏ:

Khởi tạo mảng: Mảng Arr gồm 3 phần tử kiểu Account:

  • Arr[0] = {id: 10, type: 'A'}
  • Arr[1] = {id: 20, type: 'B'}
  • Arr[2] = {id: 30, type: 'C'}

Thiết lập con trỏ:

  • Account* x = Arr;: Con trỏ x trỏ đến phần tử đầu tiên của mảng (Arr[0]).
  • Account* y = x + 2;: Dịch chuyển con trỏ đi 2 đơn vị cấu trúc, do đó y trỏ đến phần tử thứ ba của mảng (Arr[2]).

Thực thi các lệnh in:

  • cout << x->type;: Truy cập thành phần type của phần tử mà x đang trỏ tới (Arr[0]). Kết quả in ra là ký tự A.
  • cout << (y->id) - (x->id);:
    • y->id là giá trị id của Arr[2], bằng 30.
    • x->id là giá trị id của Arr[0], bằng 10.
    • Phép toán: 30−10=2030 - 10 = 20. Kết quả in ra là số 20.

Câu 15. Mô tả bài toán:​

Viết chương trình quản lý danh sách các tài khoản User gồm ID (số nguyên), Pass (chuỗi) và thực hiện các yêu cầu sau:

  1. Khai báo kiểu dữ liệu cấu trúc User.
  2. Nhập thông tin cho NN User.
  3. Hãy cho biết pass nào KHÔNG hợp lệ trong danh sách. Biết rằng Pass chỉ hợp lệ khi thỏa mãn tất cả điều kiện sau:
    • Pass phải có trên 5 ký tự.
    • Pass phải có chữ cái, chữ số và ký tự đặc biệt (Ký tự đặc biệt là các ký tự ! @ # $).

Input

  • Nhập số lượng NN User trong mảng Arr.
  • NN dòng tiếp theo, mỗi dòng là thông tin của một User.

Output

  • Xuất ra các Pass KHÔNG hợp lệ trong Arr.
  • Nếu tất cả các Pass đều hợp lệ thì xuất ra NoFound.

Gợi ý:​

  1. Khai báo kiểu dữ liệu cấu trúc User

struct User{

int ID;

string Pass;
};
  1. Nhập thông tin cho NN User.
struct NUser{ 
int n;
User *p;};

void Nhapthongtin(User &A){
cin>>A.ID>>A.Pass;
}

NUser Nhap(){
NUser ds;
cin>>ds.n;
ds.p=new User[ds.n];
for(int i=0;i<ds.n;i++){
Nhapthongtin(ds.p[i]);}
return ds;
}
  1. Hãy cho biết pass nào KHÔNG hợp lệ trong danh sách. Biết rằng Pass chỉ hợp lệ khi thỏa mãn tất cả điều kiện sau:
    • Pass phải có trên 5 ký tự.
    • Pass phải có chữ cái, chữ số và ký tự đặc biệt (Ký tự đặc biệt là các ký tự ! @ # $).
bool Check(User a){ 
bool len=false,alpha=false,digit=false,special=false;
if(a.Pass.length()>5) len=true;
for(char x:a.Pass){
if((x>='A' && x<='Z') || (x>='a' && x<='z')) alpha=true;
if(x>='0' && x<='9') digit=true;
if(x=='!' ||x=='@' || x=='#' ||x=='$') special=true;
}
if(len && alpha && digit && special) return 1;
return 0;
}

void Xuatthongtin(User a){
cout<<a.ID<<" "<<a.Pass<<endl;}

int main(){
bool ktr=0;
NUser ds;
ds=Nhap();
for(int i=0;i<ds.n;i++){
if(!Check(ds.p[i])){
Xuatthongtin(ds.p[i]);
ktr=1;
}
}
if(!ktr) cout<<"NoFound";
return 0;}

Câu 16. Mô tả bài toán:​

Viết chương trình cho phép người dùng liên tục nhập vào các số nguyên. Việc nhập chỉ DỪNG khi nhập số 0 (không tính số 0 vào dãy số nguyên) và xuất ra màn hình số nguyên có giá trị lớn thứ hai và nhỏ thứ 2 trong dãy số nguyên đã nhập.

InputOutput
50920
25923
159223
0
50920
50920
12
9220
120000
653
0
9220
653

(Lưu ý không sử dụng các cấu trúc mảng, tập hợp để giải quyết bài toán, cũng như không được sử dụng các từ khóa này trong bài làm: vector, set, map, [, ], INT_MAX, INT_MIN)


Gợi ý​

Vì không được dùng mảng ([ ]) hay các thư viện tập hợp, bạn cần dùng 4 biến riêng biệt để lưu trữ giá trị:

  • max1, max2: Lớn nhất và lớn thứ hai.
  • min1, min2: Nhỏ nhất và nhỏ thứ hai.

Cách xử lý:

  • Khởi tạo các biến bằng giá trị của số đầu tiên nhập vào.
  • Với mỗi số tiếp theo, so sánh để cập nhật thứ tự:
    • Nếu x>max1x > max1: max2=max1max2 = max1, max1=xmax1 = x.
    • Nếu x<max1x < max1 và x>max2x > max2: max2=xmax2 = x.
    • Tương tự với logic tìm min.
#include<iostream> 

using namespace std;

int main(){
int n;
int Max1=-10e9;//Lấy giá trị int bé nhất
int Max2=-10e9;
int Min1=10e9;//lấy giá trị int lớn nhất
int Min2=10e9;
cin>>n;
while(n>0){
if(n>Max1){
Max2=Max1;
Max1=n;
}

else if(n<Max1 && n>Max2){
Max2=n;
}

if(n<Min1){
Min2=Min1;
Min1=n;
}
else if(n>Min1 && n<Min2){
Min2=n;
}
cin>>n;
}
cout<<Max2<<"\n";
cout<<Min2;
return 0;