1. Trang chủ
  2. » Công Nghệ Thông Tin

Đáp án đề thi hsg tỉnh Hải Dương 20222023

10 237 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Đáp án đề thi hs giai tỉnh Hải Dương 2022-2023
Trường học Sở Giáo Dục Và Đào Tạo Hải Dương
Chuyên ngành Tin Học
Thể loại đáp án đề thi
Năm xuất bản 2022-2023
Thành phố Hải Dương
Định dạng
Số trang 10
Dung lượng 384,74 KB
File đính kèm DapAn HaiDuong 22-23.rar (357 KB)

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Page 1 SỞ GIÁO DỤC VÀ ĐÀO TẠO HẢI DƯƠNG ĐỀ CHÍNH THỨC KỲ THI CHỌN HỌC SINH GIỎI LỚP 12 THPT CẤP TỈNH NĂM HỌC 2022 – 2023 ĐÁP ÁN (Solutions) Đề thi môn TIN HỌC Bài 1 Đo chiều cao Sử dụng hệ thức lượng.

Trang 1

Page 1

SỞ GIÁO DỤC VÀ ĐÀO TẠO

HẢI DƯƠNG

ĐỀ CHÍNH THỨC

KỲ THI CHỌN HỌC SINH GIỎI LỚP 12 THPT CẤP TỈNH

NĂM HỌC 2022 – 2023

ĐÁP ÁN (Solutions)

Đề thi môn: TIN HỌC -

Bài 1: Đo chiều cao

Sử dụng hệ thức lượng trong tam giác vuông ta có công thức đáp số là:

ℎ + 𝑎 × tan(𝛼) = ℎ + 𝑎 × sin(𝛼)

cos(𝛼)

1 Chương trình Pascal:

var

a, alpha, h: double;

BEGIN

read(a, alpha, h);

alpha:=alpha*pi/180;

write(h+a*sin(alpha)/cos(alpha):0:3);

END

2 Chương trình C++:

#include <bits/stdc++.h>

using namespace std;

int main() {

double a, alpha, h;

cin >> a >> alpha >> h;

alpha = alpha * acos(-1) / 180;

printf("%.3f", h + a * tan(alpha));

}

3 Chương trình Python

import math

a = float(input())

alpha = float(input())

h = float(input())

alpha = alpha*math.pi/180

Trang 2

Page 2

print("{:.3f}".format(h + a*math.tan(alpha)))

Bài 2: Thi online

Sử dụng biến 𝑑 để lưu trữ số lần liên tiếp trước đó trả lời đúng khởi đầu 𝑑 = 0 Duyệt tất cả các ký tự từ đầu đến cuối dãy:

• Nếu ký tự gặp là ‘1’: Cộng vào kết quả 𝑑 + 1 sau đó tăng 𝑑

• Nếu ký tự gặp là ‘0’: Khởi tạo lại 𝑑 = 0

1 Chương trình Pascal

var

res: int64;

d: longint;

ch: char;

n, i: longint;

BEGIN

res:=0;

d:=0;

readln(n);

for i:=1 to n do

begin

read(ch);

res:=res + (d+1)*(ord(ch)-48);

if ch='1' then inc(d) else d:=0;

end;

writeln(res);

END

2 Chương trình C++

#include <bits/stdc++.h>

using namespace std;

int main() {

string s;

int n; cin >> n;

cin >> s;

long long ans = 0;

int d = 0;

for(int i = 0; s[i]; ++i) {

ans += (d + 1) * (s[i] - '0');

d = (s[i] - '0') ? d + 1 : 0;

}

cout << ans;

}

3 Chương trình Python

Trang 3

Page 3

n = int(input())

a = input()

d = 0

ans = 0

for i in range(n) :

if a[i]=='1' :

ans = ans + (d+1)

d = d +1

else : d=0

print(ans)

Bài 3: Chọn quà

Nhận xét rằng số gói quà mà 𝑚 bạn nữ nhận sẽ chia thành 2 phần:

• Phần 1: Gồm 𝑘 gói quà liên tiếp tính từ trái

• Phần 2: Gồm 𝑚 − 𝑘 gói quà liên tiếp tính từ phải

Bài toán qui về tính:

max

+) Giải pháp 1: (Qua 5 tests đầu) Đơn giản là sử dụng vòng lặp để tính tống:

Tham khảo giải pháp này qua chương trình Pascal sau:

var

n, m, i, k, j: longint;

a: array[0 1000000] of longint;

ans, TL, TR: int64;

BEGIN

read(n, m);

for i:=1 to n do read(a[i]);

ans:=0;

for k:=0 to m do

begin

TL:=0;

for j:=1 to k do TL:=TL+a[j];

TR:=0;

for j:=n-(m-k)+1 to n do TR:=TR + a[j];

if TL+TR>ans then ans:=TL+TR;

end;

writeln(ans);

END

+) Giải pháp 2: (Full điểm)

Chuẩn bị trước mảng 𝑠0, 𝑠1, … , 𝑠𝑛 với 𝑠𝑖 = 𝑎1+ 𝑎2 + ⋯ + 𝑎𝑖 = 𝑠𝑖−1 + 𝑎𝑖

Khi đó 𝑎1+ ⋯ + 𝑎𝑘 = 𝑠𝑘 còn 𝑎𝑛−(𝑚−𝑘)+1+ ⋯ 𝑎𝑛 = 𝑠𝑛 − 𝑠𝑛−(𝑚−𝑘)

và ta chỉ cần một vòng lặp Chương trình pascal dưới đây thực hiện ý tưởng này:

var

n, m, i: longint;

Trang 4

Page 4

a: array[0 1000000] of longint;

s: array[0 1000000] of int64;

ans, T : int64;

k: longint;

BEGIN

read(n, m);

for i:=1 to n do read(a[i]);

s[0]:=0;

for i:=1 to n do s[i]:=s[i-1]+a[i];

ans:=0;

for k:=0 to m do

begin

T:=s[k]+s[n]-s[n-(m-k)];

if T>ans then ans:=T;

end;

writeln(ans);

END

1 Giải pháp tương tự bằng C++ (full điểm):

#include <bits/stdc++.h>

#define maxn 1000001

using namespace std;

int a[maxn];

long long s[maxn];

int main() {

ios::sync_with_stdio(0);

cin.tie(0);

int n, m;

cin >> n >> m;

for(int i=1;i<=n;++i) cin >> a[i];

s[0]=0;

for(int i=1;i<=n;++i) s[i] = s[i-1] +a[i];

long long ans=0;

for(int k=0;k<=m;++k) {

long long T = s[k]+s[n]-s[n-(m-k)];

ans = max(ans,T);

}

cout << ans;

}

2 Giải pháp tương tự bằng Python (full điểm)

n, m = map(int,input().split())

a=[0]

a.extend([int(x) for x in list(input().split())])

Trang 5

Page 5

s=[0]*(n+1)

for i in range(1,n+1) : s[i]=s[i-1]+a[i]

ans=0

for k in range(m+1) :

T = s[k]+s[n]-s[n-(m-k)]

if T> ans : ans = T

print(ans)

Bài 4: Phân tích số

*) Nếu sử dụng ba vòng lặp lồng nhau qua được 2 tests Bằng cách nhận xét rằng khi biết 𝑥, 𝑦 ta có thể tính 𝑧 = 𝑛 − 𝑥 − 𝑦 do vậy chỉ cần 2 vòng lặp lồng nhau Sử dụng ý tưởng này sẽ qua được 5 tests như chương trình Pascal dưới đây:

var

n, x, y, z: longint;

ans: int64;

BEGIN

assign(input,'BAI4.inp'); reset(input);

assign(output,'BAI4.out'); rewrite(output);

read(n);

ans:=0;

for x:=1 to n do

begin

for y:=x+1 to n do

begin

z:=n-x-y;

if z<=y then break;

inc(ans);

end;

end;

writeln(ans);

END

*) Giải pháp full điểm

Trước tiên ta cần tính số bộ 𝑥, 𝑦, 𝑧 nguyên dương khác nhau thỏa mãn 𝑥 + 𝑦 + 𝑧 = 𝑛 Gọi số lượng này là 𝑇 Khi đó vì mỗi bộ (𝑥, 𝑦, 𝑧) ứng với 6 hoán vị khác nhau nên kết quả tìm được là 𝑇

Bài toán qui về tính 𝑇 Ta có:

𝑇 = 𝑃 − 𝑄

Ở đây:

Trang 6

Page 6

• 𝑃 là số bộ (𝑥, 𝑦, 𝑧) nguyên dương thỏa mãn 𝑥 + 𝑦 + 𝑧 = 𝑛 (không phân biệt khác nhau hay không)

• 𝑄 là số bộ nguyên dương 𝑥 + 𝑦 + 𝑧 = 𝑛 trong đó có ít nhất hai giá trị bằng nhau (hoặc 𝑥 = 𝑦 hoặc 𝑥 = 𝑧 hoặc 𝑦 = 𝑧)

+) Đầu tiên ta tính 𝑃

Nhận xét rằng số cặp nguyên dương (𝑢, 𝑣) thỏa mãn 𝑢 + 𝑣 = 𝑘 là 𝑘 − 1 (lần lượt với

𝑢 = 1,2, … , 𝑘 − 1; mỗi giá trị 𝑢 có một giá trị 𝑣

Do vậy ta có:

• Với 𝑥 = 1 có 𝑛 − 2 cặp (𝑦, 𝑧)

• Với 𝑥 = 2 có 𝑛 − 3 cặp (𝑦, 𝑧)

• Với 𝑥 = 𝑛 − 2 có 𝑛 − (𝑛 − 2 + 1) = 1 cặp (𝑦, 𝑧)

Do đó số bộ nguyên dương (𝑥, 𝑦, 𝑧) thỏa mãn 𝑥 + 𝑦 + 𝑧 = 𝑛 là:

𝑃 = 1 + 2 + ⋯ + (𝑛 − 2) = (𝑛 − 2)(𝑛 − 1)

2 +) Tiếp theo ta tính 𝑄

• Số bộ nguyên dương (𝑥, 𝑦, 𝑧) có 𝑥 = 𝑦 là [𝑛

2] − 1 (lần lượt thay 𝑥 = 𝑦 =

1, 2, … , [𝑛

2] − 1)

• Tương tự số bộ (𝑥, 𝑦, 𝑧) có 𝑦 = 𝑧 là [𝑛

2] − 1

• và số bộ (𝑥, 𝑦, 𝑧) có 𝑥 = 𝑧 cũng là [𝑛

2] − 1

Do vậy:

𝑄 = 3 × ([ 𝑛

2 ] − 1) Tuy nhiên khi 𝑛 chia hết cho ba thì bộ 𝑥 = 𝑦 = 𝑧 = 𝑛

3 được đếm ba lần trong khi tính

Q như trên (trong khi đó bộ này chỉ được tính một lần) Trong trường hợp này:

𝑄 = 3 × ([ 𝑛

2 ] − 1) − 2 Chương trình Pascal dưới đây minh họa ý tưởng trên (full điểm):

var T, n: int64;

BEGIN

assign(input,'BAI4.inp'); reset(input);

assign(output,'BAI4.out'); rewrite(output);

read(n);

T:=(n-2)*(n-1) div 2 -3*(n div 2-1);

if n mod 3=0 then T:=T+2;

writeln(T div 6);

END

Trang 7

Page 7

1 Chương trình tương tự bằng C++ (full điểm):

#include <bits/stdc++.h>

using namespace std;

#define task "BAI4"

int main() {

freopen(task".inp", "r", stdin);

freopen(task".out", "w", stdout);

ios::sync_with_stdio(0);

cin.tie(0);

cout.tie(0);

long long n;

cin >> n;

long long T = (n % 3) ? (n - 2) * (n - 1) / 2 - 3 * (n / 2 - 1) :

(n - 2) * (n - 1) / 2 - 3 * (n / 2 - 1)+2;

cout << T / 6;

}

2) Chương trình Python (full điểm)

with open("BAI4.inp","r") as fin :

n=int(fin.readline())

ans = (n-2) * (n-1) // 2 - 3 * (n//2 - 1)

if n % 3 == 0 : ans = ans + 2

with open("BAI4.out","w") as fout :

fout.write(str(ans // 6))

Bài 5: Tổng giá trị

Bài toán yêu cầu tính tổng:

∑ 𝑎𝑖 × 𝑎𝑗 × 𝑎𝑘

1≤𝑖<𝑗<𝑘≤𝑛

Giải pháp đơn giản là sử dụng ba vòng lặp Khi đó ta qua được 2 tests Chương trình pascal dưới đây minh họa ý tưởng này:

const

P = 1000000007;

var n, i, j, k: longint;

a: array[0 1000000] of longint;

ans: int64;

BEGIN

assign(input,'BAI5.inp'); reset(input);

assign(output,'BAI5.out'); rewrite(output);

read(n);

Trang 8

Page 8

for i:=1 to n do read(a[i]);

ans:=0;

for i:=1 to n do

for j:=i+1 to n do

for k:=j+1 to n do

ans := (ans + int64(a[i])*a[j]*a[k]) mod P;

writeln(ans);

END

Ta có thể cải tiến bằng nhận xét nếu 𝑗 < 𝑘 cố định thì:

∑ 𝑎𝑖 × 𝑎𝑗 × 𝑎𝑘

𝑖<𝑗

= (𝑎1 + 𝑎2+ ⋯ + 𝑎𝑗−1) × 𝑎𝑗 × 𝑎𝑘

Do vậy chỉ cần sử dụng 2 vòng lặp lồng nhau (khi đó qua được 5 tests) như trong chương trình pascal dưới đây:

const

P=1000000007;

var n, i, j, k: longint;

a: array[0 1000000] of longint;

ans, T: int64;

BEGIN

assign(input,'BAI5.inp'); reset(input);

assign(output,'BAI5.out'); rewrite(output);

read(n);

for i:=1 to n do read(a[i]);

ans:=0;

for j:=2 to n-1 do

begin

T:=0;

for i:=1 to j-1 do T:=(T+a[i]) mod P;

for k:=j+1 to n do

begin

ans:=(ans+T*a[j]*a[k]) mod P;

end;

end;

writeln(ans);

END

Để được full điểm ta cần phải có giải thuật 𝑂(𝑛) Nhận xét rằng:

∑ ∑ 𝑎𝑖 × 𝑎𝑗

𝑗−1

𝑖=1

= ∑ (𝑎𝑗 × ∑ 𝑎𝑖

𝑗−1

𝑖=1

) = ∑ 𝑎𝑗 × 𝑠𝑗−1

𝑢

𝑗=2

𝑢

𝑗=2

𝑢

𝑗=2

Với 𝑠𝑖 = 𝑎1+ ⋯ + 𝑎𝑖 = 𝑠𝑖−1 + 𝑎𝑖

Do vậy bằng cách dùng mảng tổng tiền tố ta có thể tính tổng :

Trang 9

Page 9

∑ 𝑎𝑖 × 𝑎𝑗

1≤𝑖<𝑗<𝑘

Trong 𝑂(𝑛) Cuối cùng chỉ còn một vòng lặp 𝑘 Chương trình pascal dưới đây minh họa ý tưởng này (full điểm):

const

maxn = 1000000;

P = 1000000007;

var n, i: longint;

a: array[0 maxn] of longint;

s: int64;

b: array[0 maxn] of int64;

res: int64;

BEGIN

assign(input,'BAI5.inp'); reset(input);

assign(output,'BAI5.out'); rewrite(output);

read(n);

for i:=1 to n do read(a[i]);

s:=a[1] mod P;

b[1]:=0;

for i:=2 to n do

begin

b[i]:=(b[i-1]+s*a[i]) mod P;

s:=(s+a[i]) mod P;

end;

res:=0;

for i:=3 to n do

begin

res:=(res + b[i-1]*a[i]) mod P;

end;

writeln(res);

END

1 Chương trình tương tự bằng C++ (full điểm):

#include <bits/stdc++.h>

#define maxn 1000005

#define MOD 1000000007

using namespace std;

int n, a[maxn];

long long b[maxn];

#define task "BAI5"

Trang 10

Page 10

int main() {

freopen(task".inp", "r", stdin);

freopen(task".out", "w", stdout);

ios::sync_with_stdio(0);

cin.tie(0);

cout.tie(0);

cin >> n;

for(int i = 1; i <= n; ++i)

cin >> a[i];

long long s = a[1] % MOD;

b[1] = 0;

for(int i = 2; i <= n; ++i) {

b[i] = (b[i - 1] + s * a[i]) % MOD;

s =(s+ a[i]) % MOD;

}

long long res = 0;

for(int i = 1; i <= n; ++i) {

res =(res + a[i] * b[i - 1]) % MOD;

}

cout << res;

}

2 Chương trình Python (full điểm)

MOD = 1000000007

a=[0]

with open("BAI5.inp","r") as fin :

n = int(fin.readline())

a.extend([int(x) for x in list(fin.readline().split())])

b=[0]*(n+1)

s=a[1]

for i in range(2,n+1) :

b[i]=(b[i-1] + s * a[i]) % MOD

s = (s + a[i]) % MOD

ans = 0

for i in range(3,n+1) :

ans = (ans + b[i-1] * a[i]) % MOD

with open("BAI5.out","w") as fout :

fout.write(str(ans))

Ngày đăng: 27/05/2023, 08:26

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w