You are on page 1of 66

Trương Đình Văn Quyền – 20215467

CÁCH ĐÁNH GIÁ ĐIỂM THỰC HÀNH


HỌC PHẦN: IT3040 - KỸ THUẬT LẬP TRÌNH – 2022.2

I. Quy định, yêu cầu:


• Tài liệu và nội dung thực hành chấm điểm trên hệ thống:
https://lab.soict.hust.edu.vn/
• Bài tập trên lớp chấm điểm tự động (các bài không chấm trên hệ thống làm
vào máy tính  làm báo cáo thực hành – Theo mẫu).
• Hạn nộp báo cáo trên Teams (Bài tập trên lớp + Bài tập về nhà): 1 tuần.

II. Đánh giá điểm thực hành


1. Chuyên cần (đúng giờ, nghiêm túc trong giờ học) - Điểm danh trên Teams: 10%
2. Báo cáo thực hành (bài tập trên lớp + Về nhà) theo mẫu nộp trên Teams: 40%
3. Trắc nghiệm – Form trên Teams: 10%
4. Kiểm tra thực hành: 40%. (Tiết 2,3 buổi thực hành thứ 5).
Điểm thưởng: 5%  10% (Cho Mục 1,2 điểm TB từ 9-10).
Tham gia thực hành đúng giờ đầy đủ theo thời khóa biểu (nếu có lý do không đi
thực hành đúng kíp được thì gửi mail xin phép thực hành bù trước 1 ngày qua mail
hoalt@soict.hust.edu.vn, Tiêu đề: đăng ký học bù – IT3040 – MaLopTH.
Các kíp có thể bù:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
TT Thời gian, địa điểm, Tuần học Mã nhóm Mã lớp
1
2
3
4
5
6
7
Nếu nghỉ không có lý do 3 buổi, không thực hành bù thì điểm chuyên cần, báo
cáo và BTVN coi như 0 điểm thực hành.

Contents
Bài thực hành số 3 – Tuần 39......................................................................................................................3
Bài tập 1: Đảo ngược một danh sách liên kết đơn...................................................................................3
Bài tập 2: Tính diện tích tam giác.............................................................................................................7
Bài tập 3: Tính tích có hướng của 2 vector..............................................................................................8
Bài tập 4: Thao tác với vector................................................................................................................10
Bài tập 5:................................................................................................................................................15
Bài tập 6:................................................................................................................................................18
Bài tập 7:................................................................................................................................................21
Bài tập 8:................................................................................................................................................24
Bài tập 9:................................................................................................................................................28
Bài tập 10: Search Engine......................................................................................................................32
Bài tập 12. Lược đồ................................................................................................................................57
Bài tập 13: Đếm xâu con........................................................................................................................61

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Bài thực hành số 3 – Tuần 39


Bài tập 1: Đảo ngược một danh sách liên kết đơn

Hãy hoàn thiện các hàm thao tác trên một danh sách liên kết:

 Thêm một phần tử vào đầu danh sách liên kết


 In danh sách
 Đảo ngược danh sách liên kết (yêu cầu độ phức tạp thời gian O(N) và chi phí
bộ nhớ dùng thêm O(1))

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

//Truong Dinh Van Quyen - 20215467

#include <iostream>

using namespace std;

struct Node {

int data;

Node* next;

Node(int data) {

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
this->data = data;

next = NULL;

};

// push a new element to the beginning of the list

Node* prepend(Node* head, int data) {

Node *newNode = new Node(data);

newNode->next = head;

return newNode;

// print the list content on a line

void print(Node* head) {

while(head){

cout<<head->data<<" ";

head = head->next;

cout<<endl;

// return the new head of the reversed list

Node* reverse(Node* head) {

Node *prev = NULL;

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
Node *next = NULL;

while(head){

next = head->next;

head->next = prev;

prev=head;

head = next;

return prev;

int main() {

int n, u;

cin >> n;

Node* head = NULL;

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

cin >> u;

head = prepend(head, u);

cout << "Original list: ";

print(head);

head = reverse(head);

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
cout << "Reversed list: ";

print(head);

return 0;

Bài tập 2: Tính diện tích tam giác

Một điểm trong không gian 2 chiều được biểu diễn bằng pair. Hãy viết hàm double
area(Point a, Point b, Point c) tính diện tích tam giác theo tọa đ ộ 3 đ ỉnh. Trong đó,
Point là kiểu được định nghĩa sẵn trong trình chấm như sau: using Point =
pair<double, double>;

//Truong Dinh Van Quyen - 20215467

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
#include <iostream>

#include <cmath>

#include <iomanip>

#include <utility>

using namespace std;

using Point = pair<double, double>;

double area(Point a, Point b, Point c) {

double ab= sqrt(pow(a.first-b.first,2)+pow(a.second-b.second,2));

double ac= sqrt(pow(a.first-c.first,2)+pow(a.second-c.second,2));

double cb= sqrt(pow(c.first-b.first,2)+pow(c.second-b.second,2));

double p = (ab+cb+ac)/2;

return sqrt(p*(p-ab)*(p-cb)*(p-ac));

int main() {

cout << setprecision(2) << fixed;

cout << area({1, 2}, {2.5, 10}, {15, -5.25}) << endl;

return 0;

Bài tập 3: Tính tích có hướng của 2 vector

Một vector trong không gian 3 chiều được biểu diễn bằng tuple<double, double,
double>. Hãy viết hàm Vector cross_product(Vector a, Vector b) tính tích có
hướng của 2 vector. Trong đó Vector là kiểu dữ liệu được định nghĩa sẵn trong
trình chấm như sau: using Vector = tuple<double, double, double>;

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

//Truong Dinh Van Quyen - 20215467

#include <iostream>

#include <cmath>

#include <iomanip>

using namespace std;

using Vector = tuple<double, double, double>;

Vector cross_product(Vector a, Vector b) {

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
return Vector(get<1>(a)*get<2>(b)-get<2>(a)*get<1>(b),

get<2>(a)*get<0>(b)-get<0>(a)*get<2>(b),

get<0>(a)*get<1>(b)-get<1>(a)*get<0>(b));

int main() {

cout << setprecision(2) << fixed;

Vector a {1.2, 4, -0.5};

Vector b {1.5, -2, 2.5};

Vector c = cross_product(a, b);

cout << get<0>(c) << ' ' << get<1>(c) << ' ' << get<2>(c) << endl;

return 0;

Bài tập 4: Thao tác với vector

Cho hai vector, hãy xóa hết các phần tử chẵn, sắp xếp giảm dần các số trong c ả 2
vector và trộn lại thành một vector cũng được sắp xếp giảm dần.

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
//Truong Dinh Van Quyen - 20215467

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

void print_vector(const vector<int> &a) {

for (int v : a) cout << v << ' ';

cout << endl;

void delete_even(vector<int> &a) {

a.erase(remove_if(a.begin(),a.end(), [] (int x) {

return x%2==0;

}),a.end());

void sort_decrease(vector<int> &a) {

sort(a.rbegin(),a.rend());

vector<int> merge_vectors(const vector<int> &a, const vector<int> &b) {

vector<int> c;

merge(a.begin(),a.end(),b.begin(),b.end(), back_inserter(c),greater<int>());

return c;

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
}

int main() {

int m, n, u;

std::vector<int> a, b;

std::cin >> m >> n;

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

std:: cin >> u;

a.push_back(u);

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

std:: cin >> u;

b.push_back(u);

delete_even(a);

cout << "Odd elements of a: ";

print_vector(a);

delete_even(b);

cout << "Odd elements of b: ";

print_vector(b);

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
sort_decrease(a);

cout << "Decreasingly sorted a: ";

print_vector(a);

sort_decrease(b);

cout << "Decreasingly sorted b: ";

print_vector(b);

vector<int> c = merge_vectors(a, b);

cout << "Decreasingly sorted c: ";

print_vector(c);

return 0;

Bài tập 5:

Viết hàm thực hiện thuật toán DFS không sử dụng đệ quy trên đồ thị biểu diễn bằng
danh sách kề vector< list<int> > . Đồ thị có n đỉnh được đánh số từ 1 đến n. Thuật
toán DFS xuất phát từ đỉnh 1. Các đỉnh được thăm theo thứ tự ưu tiên từ trái sang
phải trong danh sách kề. Yêu cầu hàm trả ra thứ tự các đỉnh được thăm (những
đỉnh không thể thăm từ đỉnh 1 thì không phải in ra).

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

//Truong Dinh Van Quyen - 20215467

#include<iostream>

#include<vector>

#include<list>

#include<stack>

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
using namespace std;

void dfs(vector< list<int> > adj) {

stack<int> S;

vector<bool> visited(adj.size());

S.push(1); // Bắt đầu từ đỉnh số 1

while(!S.empty()){

int u = S.top();

if(!visited[u]){

visited[u]=true;

cout<<u<<endl;

if(!adj[u].empty()){

int v = adj[u].front();

adj[u].pop_front();

if(!visited[v]){

S.push(v);

else S.pop();

int main() {

int n = 7;

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
vector< list<int> > adj;

adj.resize(n + 1);

adj[1].push_back(2);

adj[2].push_back(4);

adj[1].push_back(3);

adj[3].push_back(4);

adj[3].push_back(5);

adj[5].push_back(2);

adj[2].push_back(7);

adj[6].push_back(7);

dfs(adj);

Bài tập 6:

Viết hàm thực hiện thuật toán BFS không sử dụng đệ quy trên đồ thị biểu diễn bằng
danh sách kề vector< list<int> > . Đồ thị có n đỉnh được đánh số từ 1 đến n. Thuật
toán BFS xuất phát từ đỉnh 1. Các đỉnh được thăm theo thứ tự ưu tiên từ trái sang
phải trong danh sách kề. Yêu cầu hàm trả ra thứ tự các đỉnh được thăm (những
đỉnh không thể thăm từ đỉnh 1 thì không phải in ra).

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

//Truong Dinh Van Quyen - 20215467

#include<iostream>

#include<vector>

#include<list>

#include<queue>

using namespace std;

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

void bfs(vector< list<int> > adj) {

queue<int> Q;

vector<bool> visited(adj.size());

Q.push(1); // Bắt đầu từ đỉnh số 1

while(!Q.empty()){

int u = Q.front();

if(!visited[u]){

visited[u] = true;

cout<<u<<endl;

for(int v : adj[u]){

if(!visited[v]){

Q.push(v);

Q.pop();

int main() {

int n = 7;

vector< list<int> > adj;

adj.resize(n + 1);

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
adj[1].push_back(2);

adj[2].push_back(4);

adj[1].push_back(3);

adj[3].push_back(4);

adj[3].push_back(5);

adj[5].push_back(2);

adj[2].push_back(7);

adj[6].push_back(7);

bfs(adj);

Bài tập 7:

Viết các hàm thực hiện các phép giao và hợp của hai tập hợp được biểu diễn bằng
set

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

//Truong Dinh Van Quyen - 20215467

#include <iostream>

#include <set>

using namespace std;

template<class T>

set<T> set_union(const set<T> &a, const set<T> &b) {

set<T> c =a;

c.insert(b.begin(),b.end());

return c;

template<class T>

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

set<T> set_intersection(const set<T> &a, const set<T> &b) {

set<T> c;

for(const T&x : a){

if(b.find(x)!=b.end()){

c.insert(x);

return c;

template<class T>

void print_set(const std::set<T> &a) {

for (const T &x : a) {

std::cout << x << ' ';

std::cout << std::endl;

int main() {

std::set<int> a = {1, 2, 3, 5, 7};

std::set<int> b = {2, 4, 5, 6, 9};

std::set<int> c = set_union(a, b);

std::set<int> d = set_intersection(a, b);

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

std::cout << "Union: "; print_set(c);

std::cout << "Intersection: "; print_set(d);

return 0;

Bài tập 8:

Viết các hàm thực hiện các phép giao và hợp của hai tập hợp mờ được biểu diễn
bằng map.

Trong đó mỗi phần tử được gán cho một số thực trong đoạn [0..1] biểu thị độ thuộc
của phần tử trong tập hợp, với độ thuộc bằng 1 nghĩa là phần tử chắc chắn thuộc
vào tập hợp và ngược lại độ thuộc bằng 0 nghĩa là phần tử chắc chắn không thuộc
trong tập hợp.

Phép giao và hợp của 2 tập hợp được thực hiện trên các cặp phần tử bằng nhau
của 2 tập hợp, với độ thuộc mới được tính bằng phép toán min và max của hai độ
thuộc.

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

//Truong Dinh Van Quyen - 20215467

#include<iostream>

#include<map>

using namespace std;

template<class T>

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
map<T, double> fuzzy_set_union(const map<T, double> &a, const map<T,
double> &b) {

map<T, double> res = a;

for(const auto &x : b){

if (res.count(x.first)){

res[x.first] = max(res[x.first], x.second);

else res.insert(x);

return res;

template<class T>

map<T, double> fuzzy_set_intersection(const map<T, double> &a, const map<T,


double> &b) {

map<T, double> res;

for(const auto &x : a){

const auto it = b.find(x.first);

if(it != b.end())

res[x.first] = min(it->second, x.second);

return res;

template<class T>

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

void print_fuzzy_set(const map<T, double> &a) {

cout << "{ ";

for (const auto &x : a) {

cout << "(" << x.first << ", " << x.second << ") ";

cout << "}";

cout << endl;

int main () {

map<int, double> a = {{1, 0.2}, {2, 0.5}, {3, 1}, {4, 0.6}, {5, 0.7}};

map<int, double> b = {{1, 0.5}, {2, 0.4}, {4, 0.9}, {5, 0.4}, {6, 1}};

cout << "A = "; print_fuzzy_set(a);

cout << "B = "; print_fuzzy_set(b);

map<int, double> c = fuzzy_set_union(a, b);

map<int, double> d = fuzzy_set_intersection(a, b);

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
cout << "Union: "; print_fuzzy_set(c);

cout << "Intersection: "; print_fuzzy_set(d);

return 0;

Bài tập 9:

Cài đặt thuật toán Dijkstra trên đồ thị vô hướng được biểu diễn bằng danh sách kề
sử dụng priority_queue Cụ thể, bạn cần cài đặt hàm vector<int> dijkstra(const
vector< vector< pair<int, int> > >&adj) nhận đầu vào là danh sách k ề ch ứa các
cặp pair<int, int> biểu diễn đỉnh kề và trọng số tương ứng của cạnh. Đồ thị gồm n
đỉnh được đánh số từ 0 tới n-1. Hàm cần trả vector<int> chứa n phần tử lần lượt là
khoảng cách đường đi ngắn nhất từ đỉnh 0 tới các đỉnh 0, 1, 2, ..., n-1.

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

//Truong Dinh Van Quyen - 20215467

#include<iostream>

#include<vector>

#include<map>

#include<queue>

#include<climits>

using namespace std;

vector<int> dijkstra(const vector< vector< pair<int, int> > >&adj) {

priority_queue<pair<int, int>> Q;

vector<int> d(adj.size(), INT_MAX);

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
d[0] = 0; //0 là đỉnh xuất phát

Q.push({0,0});

while(!Q.empty()){

int du = -Q.top().first;

int u = Q.top().second;

Q.pop();

if(du != d[u]) continue;

for(auto e : adj[u]){

int v = e.first;

int c = e.second;

if(d[v] > d[u] + c){

d[v] = d[u] + c;

Q.push({-d[v], v});

return d;

int main() {

int n = 9;

vector< vector< pair<int, int> > > adj(n);

auto add_edge = [&adj] (int u, int v, int w) {

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
adj[u].push_back({v, w});

adj[v].push_back({u, w});

};

add_edge(0, 1, 4);

add_edge(0, 7, 8);

add_edge(1, 7, 11);

add_edge(1, 2, 8);

add_edge(2, 3, 7);

add_edge(2, 8, 2);

add_edge(3, 4, 9);

add_edge(3, 5, 14);

add_edge(4, 5, 10);

add_edge(5, 6, 2);

add_edge(6, 7, 1);

add_edge(6, 8, 6);

add_edge(7, 8, 7);

vector<int> distance = dijkstra(adj);

for (unsigned int i = 0; i < distance.size(); ++i) {

cout << "distance " << 0 << "->" << i << " = " << distance[i] << endl;

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
Bài tập 10: Search Engine

Xây dựng một máy tìm kiếm (search engine) đơn giản.
Cho N văn bản và Q truy vấn. Với mỗi truy vấn, cần trả về văn bản khớp với truy
vấn đó nhất.

Sử dụng phương pháp tính điểm TF-IDF.

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case 1:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case 2:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case 3:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case 4:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case 5:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

// Truong Dinh Van Quyen - 20215467

/*Bài tập 10: Search Engine

Xây dựng một máy tìm kiếm (search engine) đơn giản.

Cho N

văn bản và Q

truy vấn. Với mỗi truy vấn, cần trả về văn bản khớp với truy vấn đó nhất.

Sử dụng phương pháp tính điểm TF-IDF:*/

#include<iostream>

#include<cmath>

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
#include<cstring>

#include<vector>

#include<map>

#include<queue>

using namespace std;

//Định nghĩa lại so sánh trong priority queue

//priority queue chứa các cặp (x,y) trong đó x là số hiệu văn bản, y là đi ểm s ố c ủa
văn bản đó

struct cmp{

bool operator () (pair<int,int> x,pair<int,int> y){

//Văn bản điểm cao sẽ ở trên cùng

if( x.second>y.second) return false;

//2 văn bản cùng điểm thì văn bản có số hiệu thấp hơn sẽ ở trên

else if(x.second==y.second) if(x.first<y.first) return false;

else return true;

else return true;

};

//So lan xuat hien t trong d

int f(string t,int d,vector<vector<string>> &a){

int dem=0;

for(string x: a[d]) {if(t==x) dem=dem+1;}

return dem;

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
// Tìm max f(t,d) với mọi t thuộc văn bản d

int max(int d,vector<vector<string>> &a){

//1 từ sẽ tương ứng với số lần nó xuất hiện

map<string,int> M;

for(string x:a[d]) M[x]++;

int max=0;

for(auto x:M) {

//max chứa số lần xuất hiện nhiều nhất của từ xuất hiện nhiều nhất

if (x.second>max) max=x.second;

return max;

//Số văn bản chứa từ t

int df(string t,vector<vector<string>> &a){

int dem=0;

for(auto x:a){

for(auto y:x){

if(y==t) {

//có chứa t break sang văn bản tiếp theo

dem++;

break;}

return dem;

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
}

//Hàm tính điểm văn bản d với từ t

double tscore(string t,int d,vector<vector<string>> &a,int N){

//t không xuất hiện trong d thì điểm bằng 0

if (f(t,d,a)==0) return 0;

//Tính điểm theo công thức

double TF=0.5+0.5*f(t,d,a)/max(d,a);

double IDF=log2(N/df(t,a));

return TF*IDF;

int main(){

//Nhập dữ liệu từ file input.txt

freopen("input.txt","r",stdin);

int N,Q;

cin>>N;

getchar();

//VB chứa các vector là các văn bản, các vector đó chứa các từ trong v ăn b ản

vector<vector<string>> VB;

VB.resize(N);

//Nhập các văn bản

for(int i=0;i<N;i++){

string str;

str.resize(10);

char c;

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
//Biến dem dùng để nhập kí tự vào xâu

int dem=0;

L0: do{

c=getchar();

if(c=='\n') goto L1;//c là xuống dòng thì nhaỷ L1:cho xâu đang dang d ở
thành 1 từ vào văn bản hiện thời,bộ đếm về 0,reset str

else if(c==',') goto L2;//c là dấu phẩy thì lưu xâu đó thành m ột t ừ, dem v ề
0,reset str và quay L0 bắt đầu từ tiếp theo

else{

str[dem]=c;

dem++;}

}while(1);

L2:{

VB[i].push_back(str);

dem=0;

str.clear();

str.resize(10);

goto L0;};

L1:{

VB[i].push_back(str);

dem=0;

str.clear();

str.resize(10);

};

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
//Nhập các truy vấn tương tự nhập văn bản

cin>>Q;

getchar();

vector<vector<string>> TV;

TV.resize(Q);

for(int i=0;i<Q;i++){

string str;

str.resize(10);

char c;

int dem=0;

L3: do{

c=getchar();

if(c=='\n') goto L4;

else if(c==',') goto L5;

else{

str[dem]=c;

dem++;}

}while(1);

L5:{

TV[i].push_back(str);

dem=0;

str.clear();

str.resize(10);

goto L3;};

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
L4:{

TV[i].push_back(str);

dem=0;

str.clear();

str.resize(10);

};

//Hàng đợi ưu tiên

priority_queue<pair<int,int>,vector<pair<int,int>>,cmp> pq;

//Với mỗi truy vấn

for(auto x:TV){

//Với mỗi văn bản i

for(int i=0;i<N;i++){

double score=0;

//Với mỗi từ y thuộc truy vấn x ta tính điểm với từng văn bản i và cộng dồn
lại

for(auto y:x){

score=score+tscore(y,i,VB,N);

//Ta đẩy điểm của văn bản i với truy vấn x và hàng đợi

pq.push(make_pair(i,score));

//Lấy ra đỉnh của hàng đợi chính là điểm cao nhất với truy vấn x, ta c ộng 1 do
truy vấn đánh số từ 1

cout<<pq.top().first+1<<endl;

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
//xóa hàng đợi chuẩn bị sang truy vấn tiếp theo

while(!pq.empty()) {pq.pop();}

Bức tường bao quanh một lâu đài nọ được cấu thành từ n đoạn tường được đánh
số từ 1 đến n. Quân giặc lên kế hoạch tấn công lâu đài bằng cách gửi ai tên giặc
đánh vào đoạn tường thứ i. Để bảo vệ lâu đài có tất cả s lính.
Do các đoạn tường có chất lượng khác nhau nên khả năng bảo vệ tại các đoạn
tường cũng khác nhau. Cụ thể tại đoạn tường thứ i, mỗi lính có thể đẩy lùi tấn công
của ki tên giặc.
Giả sử đoạn tường thứ i có xi lính. Khi đó nếu số tên giặc không vượt quá xi×kithì
không có tên giặc nào lọt vào được qua đoạn tường này. Ngược lại sẽ có ai−xi×ki
tên giặc lọt vào lâu đài qua đoạn tường này.
Yêu cầu hãy viết chương trình phân bố lính đứng ở các đoạn tường sao cho tổng số
lính là s và tổng số lượng tên giặc lọt vào lâu đài là nhỏ nhất.

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case 1:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case 2:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case 3:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case 4:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case 5:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

// Truong Dinh Van Quyen - 20215467

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
/*Bức tường bao quanh một lâu đài nọ được cấu thành từ n

đoạn tường được đánh số từ 1 đến n

. Quân giặc lên kế hoạch tấn công lâu đài bằng cách gửi ai

tên giặc đánh vào đoạn tường thứ i

. Để bảo vệ lâu đài có tất cả s

lính.

Do các đoạn tường có chất lượng khác nhau nên khả năng bảo vệ tại các đoạn
tường cũng khác nhau. Cụ thể tại đoạn tường thứ i

, mỗi lính có thể đẩy lùi tấn công của ki

tên giặc.

Giả sử đoạn tường thứ i

có xi

lính. Khi đó nếu số tên giặc không vượt quá xi×ki

thì không có tên giặc nào lọt vào được qua đoạn tường này. Ngược lại sẽ có
ai−xi×ki

tên giặc lọt vào lâu đài qua đoạn tường này.

Yêu cầu hãy viết chương trình phân bố lính đứng ở các đoạn tường sao cho tổng số
lính là s

và tổng số lượng tên giặc lọt vào lâu đài là nhỏ nhất.*/

#include<iostream>

#include<map>

#include<queue>

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
using namespace std;

//Định nghĩa lại so sánh trong hàng đợi ưu tiên

//Ta sẽ ưu tiên độ giảm thiệt hại lên đầu

struct cmp{

//x y là cặp : first là số tên địch còn lại,second là khả năng chống trả

bool operator () (pair<int,int> x,pair<int,int> y){

//Biến lưu giá trị giảm thiệt hại

int gth1,gth2;

//Nếu số tên địch > Khả năng chống trả thì nếu thêm 1 lính độ giảm thiệt hại
=khả năng chống trả

//Ngược lại thì = số tên địch

gth1=(x.first-x.second>=0)?x.second:x.first;

gth2=(y.first-y.second>=0)?y.second:y.first;

//Giảm thiệt hại lớn được ưu tiên

if(gth1>gth2) return false;

else return true;

};

int main(){

int n, s;

cin>>n>>s;

priority_queue<pair<int,int>,vector<pair<int,int>>,cmp> pq;

int arr[2*n]={};

//Cho các input vào hàng đợi

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
for(int i=0;i<2*n;i++){

cin>>arr[i];

if(i%2==1) pq.push(make_pair(arr[i-1],arr[i]));

pair<int,int> temp;

//Khi vẫn còn lính

while(s>0){

//Cho thêm 1 lính vào tường tương ứng với độ giảm thiệt hại cao

temp=pq.top();

//pop phần tử trên đầu và cập nhật lại số địch

pq.pop();

temp.first=temp.first-temp.second;

pq.push(temp);

s--;

//Tính số địch lọt vào lâu đài

int count;

//Lấy các phần tử trong hàng đợi để tính kết quả

while(!pq.empty()){

//số địch >0 tức là sẽ bị địch lọt vào lâu đài

//Ngược lại thì không có tên địch lọt vào lâu đài

if(pq.top().first>0) count=count+pq.top().first;

pq.pop();

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
cout<<count;

Bài tập 12. Lược đồ


Cho một lược đồ gồm n cột chữ nhật liên tiếp nhau có chiều rộng bằng 1 và chiều
cao lần lượt là các số nguyên không âm h1,h2,…,hn Hãy xác định hình chữ nhật có
diện tích lớn nhất có thể tạo thành từ các cột liên tiếp.
Dữ liệu vào:
Dòng thứ nhất chứa số nguyên dương n (1≤n≤106 ).
Dòng thứ hai chứa n số nguyên không âm h1,h2,…,hn cách nhau bởi dấu cách
(0≤hi≤109 ).

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case1:

Case2:

Case3:

Case4:

//Truong Dinh Van Quyen - 2021567

/*Bài tập 12. Lược đồ

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
Cho một lược đồ gồm n

cột chữ nhật liên tiếp nhau có chiều rộng bằng 1 và chiều cao lần lượt là các số
nguyên không âm h1,h2,…,hn

. Hãy xác định hình chữ nhật có diện tích lớn nhất có thể tạo thành từ các cột liên
tiếp.*/

#include<iostream>

#include<vector>

#include<queue>

using namespace std;

//Ý tưởng: Mỗi hcn dc tạo thành đều có một hình chữ nhật con có h bé nhất

//Từ mỗi hcn con cao hi ta xây dựng hcn to có S lớn nhất mà hi là bé nhất b ằng
cách loang rộng ra 2 bên cho đến khi gặp hcn có hj nhỏ hơn

//Tìm Smax trong các S đó

int main(){

//Nhập input từ file input1.txt

freopen("input1.txt","r",stdin);

int N;

cin>>N;

//mảng chứa chiều cao các hcn

int arr[N];

for(int i=0;i<N;i++){

cin>>arr[i];

//Lưu giá trị S lớn nhất hiện tại

int max=0;

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
for(int i=0;i<N;i++){

int L=0;//So hcn lien tiep ben trai hcn hi co chieu cao>=hi

int R=0;//So hcn lien tiep ben phai hcn hi co chieu cao>=hi

int j=i-1;

//Nếu chiều cao hcn i nhân với tổng số hcn vẫn nhỏ hơn max hiện thời thì b ỏ
qua hcn này

if(arr[i]*N<=max) continue;

while(j>=0){

if(arr[j]>=arr[i]) {L++;j--;continue;}

else break;

j=i+1;

while(j<N){

if(arr[j]>=arr[i]) {R++;j++;continue;}

else break;

//Tính diện tích hcn to tìm dc

if((L+R+1)*arr[i]>max) max=(L+R+1)*arr[i];

cout<<max;

return 1;

Bài tập 13: Đếm xâu con


Cho một xâu nhị phân độ dài n. Hãy viết chương trình đếm số lượng xâu con chứa
số ký tự 0 và số ký tự 1 bằng nhau.

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case1:

Case2:

Case3:

Case4:

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467

Case5:

//Truong Dinh Van Quyen - 20215467

/*Bài tập 13: Đếm xâu con

Cho một xâu nhị phân độ dài n

. Hãy viết chương trình đếm số lượng xâu con chứa số ký tự 0 và số ký tự 1 bằng
nhau.*/

#include<iostream>

#include<cstring>

#include<vector>

using namespace std;

int main(){

//Nhập input từ file input3.txt

freopen("input3.txt","r",stdin);

//str chứa xâu nhị phân nhập vào

string str;

cin>>str;

vector<int> a;

//dem0 là tổng số lượng số 0,dem1 là tổng số lượng số 1

//dasd0 là số số 0 đã xét qua,dasd là số số 1 đã xét qua

int dem0=0,dem1=0,dasd0=0,dasd1=0;

//push các giá trị 0,1 vào vector

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
for(int i=0;i<str.length();i++){

if(str[i]=='0') {a.push_back(0);dem0++;}

else {a.push_back(1);dem1++;}

int N=a.size();

//đếm số lượng xâu cần tìm

int dem=0;

//Xét từ phần tử i

for(int i=0;i<N;i++){

//S biểu diễn cho sự cân bằng giữa 0 và 1

int S=0;

//Nếu phần tử đầu là 0 thì độ cân bằng - đi 1, cập nhật dasd0

if(a[i]==0) {S--;dasd0++;}

//Phần tử đầu là 1 thì độ cân bằng +1, cập nhật dasd1

else {S++;dasd1++;}

//tmp để lưu giá trị của dasd để dùng cho vòng lặp

int tmp0=dasd0,tmp1=dasd1;

//Xét lần lượt các phần tử sau i

for(int j=i+1;j<N;j++){

//=0 thì giảm độ cân bằng và tăng tmp0

if(a[j]==0) {S--;tmp0++;}

//Ngược lại tăng độ cân bằng tăng tmp1

else {S++;tmp1++;}

IT3040 – 2022.2 – Mã lớp TH:727636


Trương Đình Văn Quyền – 20215467
//Độ cân bằng =0 tức là xâu từ phần tử thứ i đến thứ j thỏa mã điều kiện,
tăng dem thêm 1

if(S==0) dem++;

//Nếu S<0 tức xâu hiện đang xét nhiều 0 hơn 1, nếu các ph ần t ử 1 ch ưa xét
đến(dem1-tmp) không đủ để xâu về cân bằng thì break

else if((S<0)&&(S+dem1-tmp1<0)) break;

//Tương tự với S>0

else if((S>0)&&(S-dem0+tmp0>0)) break;

cout<<dem;

IT3040 – 2022.2 – Mã lớp TH:727636

You might also like