GIẢI MỘT SỐ BÀI TOÁN BẰNG STL

Một phần của tài liệu Giaso trình Lập trình C++ ppt (Trang 43 - 49)

XIV.1. Quản lý sinh viên

XIV.1.1. Đề bài

Tên file: SVIEN.*

Dữ liệu vào: từ file B1.INP, gồm:

- Dòng 1: Số sinh viên của trường (n – n<=10000)

- 3*n dòng tiếp theo: Thông tin của 1 sinh viên được ghi trên 3 dòng, bao gồm: Họ tên (tối đa 20 ký tự), lớp (tối đa 6 ký tự), quê quán (tối đa 10 ký tự)

Yêu cầu: Tìm và liệt kê:

- Số lượng lớp trong trường và danh sách các lớp - Với mỗi lớp:

o Số lượng và danh sách các địa phương là quê quán của sinh viên trong lớp

Dữ liệu ra: tại file B1.OUT với khuôn dạng như sau: - Dòng 1: Số lớp của trường (k)

- Các dòng tiếp theo là thông tin của từng lớp (mỗi mục được liệt kê dưới đây được trình bày trên 1 dòng):

o Ten lop

o số sinh viên của lớp, số lượng địa phương (m)

o số lượng sinh viên quê ở địa phương 1, tên địa phương 1

o số lượng sinh viên quê ở địa phương 2, tên địa phương 2

o ...

o số lượng sinh viên quê ở địa phương m, tên địa phương m

B1.INP B1.OUT 5 Nguyen Van A 46pm1 Hung Yen Tran Van B 47th1 Hai Duong Nguyen Thi C 46pm1 Hung Yen Vu Van D 47th1 Binh Dinh Cao Thi E 47th1 Hai Duong 2 46pm1 2 1 2 Hung Yen 47th1 3 2 2 Hai Duong 1 Binh Dinh

XIV.1.2. Bài giải

#include <iostream> #include <fstream> #include <string> #include <map> using namespace std; #define INPUT "b1.inp" #define OUTPUT "b1.out" int main() {

ifstream fi; int n, i;

map<string, int> lop; // map giữa tên lớp và số sinh viên map<string, map<string, int> > que; // map giữa tên lớp và biến đếm số // sinh viên của từng quê

// biến đếm này cũng là ánh xạ giữa quê // và số sinh viên ở quê đó

fi.open(INPUT); // Mở file input fi >> n; // Số lượng sinh viên char sLop[100], sQue[100];

fi.getline(sLop, 100); // Đọc xuống dòng (sau n) for (int i=0; i<n; i++) {

fi.getline(sLop, 100); // Đọc tên (ko sử dụng) fi.getline(sLop, 100); // Đọc tên lớp

lop[sLop]++; // Thêm số sinh viên của lớp đó fi.getline(sQue, 100); // Đọc quê

}

fi.close(); // Đóng file input ofstream fo;

fo.open(OUTPUT); // Mở file output map<string, int>::iterator j;

fo << lop.size() << endl; // Ghi số lượng lớp for (j=lop.begin(); j!=lop.end(); j++) {// Lặp qua từng lớp

fo << j->first << endl; // Ghi tên lớp (thành phần đầu của pair) map<string, int> &quei = que[j->first];

// Gán biến tham chiếu đến biến đếm quê // Của lớp tương ứng

fo << j->second << " " << quei.size() << endl; // Ghi số lượng sinh viên của lớp và

// số lượng quê quán của sv trong lớp map<string, int>::iterator t;

for (t=quei.begin(); t!=quei.end(); t++) { // Với mỗi vùng quê, ghi số lượng sv // ở quê đó và tên quê

fo << t->second << " " << t->first << endl; }

}

fo.close(); // Đóng file output } /********************* Test1 *************************** 5 Nguyen Van A 46pm1 Hung Yen Tran Van B 47th1 Hai Duong Nguyen Thi C 46pm1 Hung Yen Vu Van D 47th1 Binh Dinh Cao Thi E 47th1 Hai Duong ********************************************************/ XIV.2. Rào đất XIV.2.1. Đề bài

Tên file: RAO.*

- Một mảnh đất hình chữ nhật (kích thước tối đa 32000x32000) được rào bằng các tường rào song song với các cạnh của hình chữ nhật

- Một khoảng đất được gọi là được bảo vệ nếu nó được giới hạn bởi các tường rào - Hãy tìm khoảng đất có diện tích lớn nhất được bảo vệ

Dữ liệu vào: từ file RAO.INP

- Dòng đầu: 2 số nguyên w h là chiều rộng và chiều cao của mảnh đất - Dòng thứ 2: số dòng lượng tường rào (n<=100)

- n dòng tiếp theo: mỗi dòng gồm 4 số nguyên (cách nhau bởi dấu cách) là tọa độ 2 điểm đầu và cuối của rào. Dữ liệu vào đảm bảo là rào song song với cạnh của hình chữ nhật

Dữ liệu ra: tại file B2.OUT, gồm:

XIV.2.2. Bài giải

XIV.3. Robot

XIV.3.1. Đề bài

Bài 3 (Robot). Tên file: ROBOT.*

Một con robot di chuyển trên một lưới ô vuông bằng cách nhận một trong các lệnh sau:  R: Quay phải 45 độ

 L: Quay trái 45 độ

 G n: Tiến về phía trước 1 khoảng n (n < 1000)  U: Nhấc chổi lên

 D: Hạ chổi xuống

(chú ý rằng khi hạ chổi xuống là ô đó đã được tô màu)

Trạng thái ban đầu của robot là nhấc chổi, tọa độ ban đầu là điểm (0, 0) Input: Nhạp dữ liệu từ file input.txt gồm các thông tin sau

 Mỗi dòng là 1 trong 5 lệnh kể trên (tối đa 1000 lệnh) Output: Kết quả ghi ra file output.txt

 Dòng đầu tiên là 1 số nguyên chỉ ra số lượng ô được tô màu

XIV.3.2. Bài giải

#include <iostream> #include <fstream> #include <string> #include <map> using namespace std; #define INPUT "robot.inp" #define OUTPUT "robot.out"

class diem { // Lớp điểm, lưu tọa độ của điểm public:

int x, y; // Toạ độ của điểm

diem() {} // Hàm khởi tạo điểm (không tham số) diem(int _x, int _y) {// Hàm khởi tạo diểm theo tọa độ

x = _x; y = _y;

} // Hàm so sánh điểm với điểm khác // Hàm này sử dụng để sắp xếp các khóa trong map

bool operator < (const diem& b) const { return (x<b.x) || (x==b.x && y<b.y); }

};

map<diem, int> A; // Ánh xạ giữa điểm và một số nguyên (nếu số nguyên // khác 0 tức là điểm đó đã đi qua)

int main() {

ifstream fi; fi.open(INPUT); string s;

int huong = 0; // Hướng khởi đầu

int dx[] = {1,0,-1,0};// Vector di chuyển tương ứng theo hướng int dy[] = {0,-1,0,1};

int n, i, x=0, y=0; // Tọa độ đầu tiên bool choi = false; // Trạng thái của chổi while (!fi.eof()) { // Đọc đến khi hết file

s = "";

switch (s[0]) { // Kiểm tra ký tự đầu case 'R': // R: Quay phải

huong = (huong+1)%4; break;

case 'L': // L: Quay trái huong = (huong+3)%4;

break;

case 'G': // Tiến theo hướng hiện tại fi >> n; // Đọc thêm giá trị n for (i=0; i<n-1; i++) {

x += dx[huong]; // dịch chuyển từng bước

y += dy[huong]; // Đếm các ô nếu trạng thái chổi là hạ xuống if (choi) A[diem(x, y)] ++;

} break;

case 'U': // Nhấc chổi choi = false;

break;

case 'D': // Hạ chổi choi = true;

A[diem(x, y)] ++; // Đếm luôn ô vừa hạ break; } } fi.close(); ofstream fo; fo.open(OUTPUT); fo << A.size(); fo.close(); } /****** Test 1 ********* U D U D ***********************/ /****** Test 2 ********* U D U D G 100 L L G 100 XIV.4. Dijsktra XIV.4.1. Đề bài

XIV.4.2. Bài giải

XIV.5. Hợp diện tích hình chữ nhật

XIV.5.1. Đề bài

Cho n hình chữ nhật có cạnh song song với các trục Ox, Oy. Tìm tổng diện tích không gian bị che bởi các hình chữ nhật này (Diện tích phần hợp của các hình chữ nhật);

XIV.5.2. Bài giải

. Kéo dài các cạnh đứng

. Kéo dài các cạnh ngang

. Các cạnh này chia không gian thành một lưới hình chữ nhật. - Mỗi hình chữ nhật sẽ che một số ô trong lưới này

- Đếm tổng diện tích của các ô bị che, bạn tính được diện tích của phần che phủ của tất cả các hình chữ nhật.

/*

Cho 1 danh sach cac hinh chu nhat co canh song song voi man hinh Tim hinh chu nhat co dien tich la hop cua cac hinh chu nhat nay */ #include <iostream> #include <fstream> #include <vector> #include <map> #include <algorithm>

#define input "dientich.inp" #define output "dientich.out" using namespace std;

typedef vector<int> dong;

struct chunhat // Thông tin của 1 hình chữ nhật {

double xmin, ymin, xmax, ymax; // xmin, xmax, ymin, ymax };

int n;

vector<dong> a; // Bảng đánh dấu các ô bị che vector<chunhat> cn; // Danh sách các hình chữ nhật

vector<double> tx, ty; // Tọa độ các lưới dọc và ngang inline void swap(double &a, double &b) // Hàm đổi chỗ 2 số thực {

double t = a; a = b; b = t; // Hàm khai báo inline để chạy nhanh hơn } int main() { fstream f(input); f >> n; f.get(); // Số hình chữ nhật cn.resize(n);

for (int i=0; i<n; i++) // Đọc thông tin từng hình chữ nhật {

chunhat &a = cn[i]; // Đổi chỗ nếu các tọa độ không hợp lệ f >> a.xmin >> a.ymin >> a.xmax >> a.ymax; f.get();

if (a.xmin>a.xmax) swap(a.xmin, a.xmax); if (a.ymin>a.ymax) swap(a.ymin, a.ymax);

tx.push_back(a.xmin); // Tạo mảng tx: tọa độ các lưới đứng tx.push_back(a.xmax);

ty.push_back(a.ymin); // Tạo mảng ty: tọa độ các lưới ngang ty.push_back(a.ymax);

}

f.close();

sort(tx.begin(), tx.end()); // Sắp xếp các tọa độ lưới dứng và ngang sort(ty.begin(), ty.end());

map<double, int> mx, my; // Bảng ánh xạ giữa tọa độ (số thực) for (int i=0; i<2*n; i++) // và số thứ tự

{ // của tọa độ đó trên lưới (số nguyên) mx[tx[i]] = i;

my[ty[i]] = i; }

a.resize(2*n); // Tạo mảng (2n)*(2n), toàn số 0 for (int i=0; i<2*n; i++) a[i].resize(2*n, 0);

double dt = 0; // Tính tổng diện tích for (int i=0; i<n; i++)

{

chunhat b = cn[i];

int xmin = mx[b.xmin]; // xmin, xmax: chỉ số cạnh trái, phải int ymin = my[b.ymin]; // trên lưới

int xmax = mx[b.xmax]; // ymin, ymax: chỉ số các cạnh trên, dưới int ymax = my[b.ymax]; // trên lưới

for (int x=xmin; x<xmax; x++) // Duyệt qua tất cả các thuộc hcnhật for (int y=ymin; y<ymax; y++) {

if (a[x][y]==0) // Nếu ô chưa được đánh dấu {

a[x][y] = 1; // Đánh dấu ô đó, và tính thêm diện tích dt += (tx[x+1]-tx[x])*(ty[y+1]-ty[y]); } } } ofstream fo; fo.open(output); fo << dt; // Tổng diện tích của các hình chữ nhật fo.close(); } /* 2 0 0 1 1 0 0 2 2 */ XV. INPUT VÀ OUTPUT

Một phần của tài liệu Giaso trình Lập trình C++ ppt (Trang 43 - 49)

Tải bản đầy đủ (PDF)

(49 trang)