Solving the Following Questions with C++

Introduction

With the last post available for a while, it is time to go on more questions with C++. It is served as schoolwork for most learners.

Stage 1

The first stage is described in detail in the former post.

Stage 2

Question 2.1

Given three integer mm, nn and xx and 0<x<m<n0<x<m<n, code a program that outputs all the integers in [m,n][m, n], divide xx into which, with remainder less than 5. Finally, output the sum of the squares of these integers.

Sample I/O

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Input: 11
Input: 25
Input: 8
Outputs:
11
12
16
17
18
19
20
24
25
Sum of Squares: 3096

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
///
/// @file 04-range-remainders.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 2, 2024
/// @version 0.2
/// @brief The use of math theorem, permutation and logic.
///

#include <iostream>

int main(int argc, char* argv[]) {
int m, n, x, counter = 0, sum = 0;
// first step: get the value of m, n and x
std::cout << "Input: m=";
std::cin >> m;
std::cout << "Input: n=";
std::cin >> n;
std::cout << "Input: x=";
std::cin >> x;
// next step: ensuring the inputs are correct, traverse the integers in [m, n]
// then judge if each integer satisfies the requirements
if (x > 0 && m > x && n > m) {
std::cout << "Outputs:" << std::endl;
for (int output = m; output <= n; output++) {
int remainder = output % x;
if (remainder < 5) {
cout << output << endl;
sum += output * output;
counter++;
}
}
if (counter == 0) {
std::cout << "NONE" << std::endl;
}
std::cout << "Sum of Squares: " << sum << std::endl;
}
else {
std::cout << "Input(s) invalid. Inputs must satisfy 0<x<m<n!" << std::endl;
}
return 0;
}

Question 2.2

Code to meet the following functions.
Within an infinite loop, allow the user to input one integer a time continuously. When a second 0 is inputed, stop the loop and output the sum between the two inputs of 0.

Sample I/O

1
2
3
4
5
6
Input: 16
Input: 0
Input: -38
Input: 25
Input: 0
Output: -13
1
2
3
4
5
Input: -71
Input: 35
Input: 0
Input: 0
Output: 0

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
///
/// @file 05-sum-with-valid-range.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 2, 2024
/// @version 0.2
/// @brief The use of math theorem, permutation and logic.
///

#include <iostream>

int main(int argc, char* argv[]) {
// Step 1: define the variables with initial value specified for the judgement that the input is not 0
// Note that "invalid" and "valid" should be non-zero, or the loops are in vain.
int invalid = 233, valid = 233, sum = 0;
std::vector<int> result;
// Step 2: allow inputting any invalid non-zero values until the first 0 is input
while (invalid != 0) {
std::cout << "Input: ";
std::cin >> invalid;
}
// Step 3: sum all the valid values until a second 0 is input
// Possible improvement: reduce space complexity to O(1).
for (counter = 0; valid != 0; counter++) {
std::cout << "Input: ";
std::cin >> valid;
result.insert(result.begin() + counter, valid);
}
for (int i = 0; i < counter; i++) {
sum += result[i];
}
// Finally, output the sum
std::cout << "Output: " << sum << std::endl;
return 0;
}

Stage 3

Question 3.1

Code to meet the following functions.
Given 16 double-digit integers (not repeating in the range of 10 ~ 99), put them into a 4×44\times4 matrix so that they are arranged from large to small in the order shown in the figure below.
Matrix of Question 3.1
Then after inputting another double-digit integer, search the matrix for it and output the coordination if found; else output "Not Found".

Postscript

Just correctly output which row and which column. There is no need to define a 2-dimensional array.

Sample I/O

1
2
3
Input: 15 42 92 30 37 19 24 60 21 66 71 36 84 58 79 53
Input: 36
Output: 2, 0
1
2
3
Input: 15 42 92 30 37 19 24 60 21 66 71 36 84 58 79 53
Input: 35
Output: Not Found

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
///
/// @file 06-sort-and-search.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 3, 2024
/// @version 0.2
/// @brief The use of bubble sort and binary search.
///

#include <iostream>

int main(int argc, const char* argv[]) {
// Step 1: considering no need of 2-d array, therefore a 1-d array is defined
int a[16], low, high, mid, input;
bool finished, right = true, down = true;
std::cout << "Input: ";
for (int i = 0; i < 16; i++)
std::cin >> a[i];
// Step 2: using bubble sort algorithm, arrange each element of the array from large to small, time complexity: O(n*n)
for (int i = 1; i < 16; i++) {
// Note that the following "finished" is hypothesized as true. It will turn into false unless the following loop changes nothing of the array.
finished = true;
for (int j = 0; j < 16 - i; j++) {
if (a[j] < a[j + 1]) {
finished = false;
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
if (finished)
break;
}
// Step 3: following the sequence by size of each element of the matrix above, first search for the input, and then output the answer
std::cout << "Input: ";
std::cin >> input;
std::cout << "Output: ";
low = 0;
high = 15;
while (low <= high) {
mid = (low + high) / 2;
if (input == a[mid])
break;
if (input < a[mid])
low = mid + 1;
else
high = mid - 1;
}
if (low > high)
std::cout << "Not Found" << std::endl;
else {
// Note that the size and the rule of sequence of the matrix is fixed, so there is no need to invent an algorithm to satisfy the feature. Only 16 cases are to be considered.
switch (mid) {
case 0:
std::cout << "0, 0" << std::endl;
break;
case 1:
std::cout << "0, 1" << std::endl;
break;
case 2:
std::cout << "0, 2" << std::endl;
break;
case 3:
std::cout << "0, 3" << std::endl;
break;
case 4:
std::cout << "1, 3" << std::endl;
break;
case 5:
std::cout << "2, 3" << std::endl;
break;
case 6:
std::cout << "3, 3" << std::endl;
break;
case 7:
std::cout << "3, 2" << std::endl;
break;
case 8:
std::cout << "3, 1" << std::endl;
break;
case 9:
std::cout << "3, 0" << std::endl;
break;
case 10:
std::cout << "2, 0" << std::endl;
break;
case 11:
std::cout << "1, 0" << std::endl;
break;
case 12:
std::cout << "1, 1" << std::endl;
break;
case 13:
std::cout << "1, 2" << std::endl;
break;
case 14:
std::cout << "2, 2" << std::endl;
break;
case 15:
std::cout << "2, 1" << std::endl;
break;
default:
std::cout << "Internal Method Error. Sorry about this!" << std::endl;
}
}
return 0;
}

Question 3.2

Code to meet the following functions.
There is an English sentence with letters and spaces only (no punctuations or other non-alphabetic symbols), in which every word is less than 10 letters, and the sentence is no more than 10 words. Connect all words with the same length to a longer “word”. Output the “words” after connection from short to long. If the “words” after connection share the same length, put the word with more connection operations in the front.

Sample I/O

1
2
Input: This is a good day for us to work
Output: a isusto dayfor Thisgoodwork
1
2
Input: This is a bad day for us to work
Output: a isusto Thiswork baddayfor

Solution

It is not easy for most first learners. It seems much harder than the first look.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
///
/// @file 07-rearrange-words.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 3, 2024
/// @version 0.2
/// @brief The use of math theorem, permutation and logic.
///

#include <iostream>

int main(int argc, const char* argv[]) {
using namespace std;
char words[10][11], sentence[110], key = ' ';
int counter = 0, length[10] = {0}, total_length[10] = {0};
// Step 1: get the line of the special sentence; 110 equals to 10(words) times 11(maximum size -- 10 -- of a word, with additional one character '\0')
std::cout << "Input: ";
std::cin.getline(sentence, 110);
std::cout << "Output: ";
// Step 2: count the total words and save the count
for (int i = 0; sentence[i] != '\0'; i++) {
if (key == ' ' && sentence[i] != ' ')
counter++;
key = sentence[i];
}
// Step 3: calculate the lengths of the words and store them into an array
key = ' ';
for (int i = -1, j = 0; i < counter && key != '\0'; j++) {
if (key == ' ' && sentence[j] != ' ')
i++;
while (sentence[j] != '\0')
if (sentence[j] != ' ') {
length[i]++;
j++;
}
else
break;
key = sentence[j];
}
// Step 4: split each word into different rows in a two-dimensional array
for (int i = 0, k = 0; i < counter; i++) {
for (int j = 0; j < length[i]; j++, k++)
words[i][j] = sentence[k];
while (sentence[k] == ' ')
k++;
}
// Step 5: calculate the total length of words sharing the same (1~10) lengths
for (int i = 1; i <= 10; i++)
for (int j = 0; j < counter; j++)
if (length[j] == i)
total_length[i - 1] += i;
// Step 6: by traverse, output "words" from short to long
// Considering the total length is no more than 100, therefore just try every possible total length.
for (int sum = 1; sum <= 100; sum++)
for (int i = 0; i < 10; i++)
if (total_length[i] == sum) {
for (int j = 0; j < counter; j++)
if (length[j] == i + 1)
for (int k = 0; k < length[j]; k++)
std::cout << words[j][k];
std::cout << ' ';
}
std::cout << std::flush;
return 0;
}

Stage 4

Question 4.1

Define an array int arr[7] in function main() that stores 7 natural numbers smaller than 15 (repetition exists). To process arr, you will design a function called myfun(), which returns the sum of the numbers where there are odd non-zero integers in arr, or returns the product of the non-zero integers when they are even. Finally, output the returned value in main(). However, there are restrictions below:

  1. myfun() has only one parameter, which transmits the argument arr.
  2. In myfun(), only one loop, which is specifically an ordinary counter loop, is allowed.
  3. There are no conditional, relational, or logical expressions in the whole program except for this loop control line. Note that if, switch, loop control lines, question mark colon expressions, etc. are conditional expressions.

Sample I/O

1
2
Input: 14 2 0 13 7 9 0
Output: 45
1
2
Input: 5 12 0 0 7 1 0
Output: 420

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
///
/// @file 08-no-loops-condition-logic.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 4, 2024
/// @version 0.2
/// @brief The use of function, enumeration and boolean algebra.
/// @note The use of condition expressions, logic expressions,
/// relation expressions and loops are not allowed in this file.
///

#include <iostream>

int myfun(int *arr) {
// Step 1: use as many local variables as possible for easier calculation
int result, sum = 0, product = 1;
bool result_is_product = true;
bool not_zero = true;
// if current element is not zero
not_zero = arr[0];
// the result to return is flipped, else do not change the value
result_is_product = (not_zero * (true - result_is_product)) +
((true - not_zero) * (result_is_product));
// add the element to the sum and multiply the product
sum += arr[0];
product *= ((int)not_zero * arr[0] + (int)(true - not_zero));
// do the things above 7 times (7 is the size of input elements in function
// "main") If the question does not imply the size, this function must
// involve an infinite loop to finish calculation.
not_zero = arr[1];
result_is_product = (not_zero * (true - result_is_product)) +
((true - not_zero) * (result_is_product));
sum += arr[1];
product *= ((int)not_zero * arr[1] + (int)(true - not_zero));
// 2
not_zero = arr[2];
result_is_product = (not_zero * (true - result_is_product)) +
((true - not_zero) * (result_is_product));
sum += arr[2];
product *= ((int)not_zero * arr[2] + (int)(true - not_zero));
// 3
not_zero = arr[3];
result_is_product = (not_zero * (true - result_is_product)) +
((true - not_zero) * (result_is_product));
sum += arr[3];
product *= ((int)not_zero * arr[3] + (int)(true - not_zero));
// 4
not_zero = arr[4];
result_is_product = (not_zero * (true - result_is_product)) +
((true - not_zero) * (result_is_product));
sum += arr[4];
product *= ((int)not_zero * arr[4] + (int)(true - not_zero));
// 5
not_zero = arr[5];
result_is_product = (not_zero * (true - result_is_product)) +
((true - not_zero) * (result_is_product));
sum += arr[5];
product *= ((int)not_zero * arr[5] + (int)(true - not_zero));
// 6
not_zero = arr[6];
result_is_product = (not_zero * (true - result_is_product)) +
((true - not_zero) * (result_is_product));
sum += arr[6];
product *= ((int)not_zero * arr[6] + (int)(true - not_zero));
// What to return? Let's determine it.
result = ((int)result_is_product * product +
(int)(true - result_is_product) * sum);
return result;
}

int main(int argc, const char* argv[]) {
int arr[7];
std::cout << "Input: " << std::flush;
std::cin >> arr[0] >> arr[1] >> arr[2] >> arr[3] >> arr[4] >> arr[5] >> arr[6];
std::cout << "Output: " << myfun(arr) << std::endl;
return 0;
}

Question 4.2

Given the following function main(),

1
2
3
4
5
6
7
8
9
10
11
12
13
int main(int argc, const char* argv[]) {
int a[3];
double b[3];

std::cout << SpaceCounter(a[0]);
std::cout << SpaceCounter(a[1]);
std::cout << SpaceCounter(a[2]);
std::cout << SpaceCounter(b[0]);
std::cout << SpaceCounter(b[1]);
std::cout << SpaceCounter(b[2]);

return 0;
}

and the result that the main() outputs 481281624, please design the function SpaceCounter(), with the restrictions below:

  1. No function overloads and global variables are used.
  2. The function body should be no more than three semicolons and no commas.
  3. No libraries other than iostream are included.
  4. The program exits properly at the last line of main().

Note that the arrays a and b have no initial values, and their elements may be random values.

Solution

This question was once proven to be with ill restrictions. However, using more tricks gives a more perfect answer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

size_t SpaceCounter(int, double = 0.0);

int main(int argc, const char* argv[]) {
int a[3];
double b[3];

std::cout << SpaceCounter(a[0]);
std::cout << SpaceCounter(a[1]);
std::cout << SpaceCounter(a[2]);
std::cout << SpaceCounter(b[0]);
std::cout << SpaceCounter(b[1]);
std::cout << SpaceCounter(b[2]);

return 0;
}

size_t SpaceCounter(int integer, double hidden) {
static int count = 0;
count++;
return sizeof(integer) * (count <= 3 ? count : 0) + sizeof(hidden) * (count <= 3 ? 0 : count - 3);
}

The solution can also be simplified into a situation where a function is called multiple times, making static variables change.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
///
/// @file 09-function-fixed-return.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 4, 2024
/// @version 0.2
/// @brief The use of static function variable.
/// @note Do not overload functions. No global variables.
/// No more than three semicolons(;) and no commas(,) in function "SpaceCounter".
/// Do not include libraries other than "iostream".
/// The function "main" must completely executed without early exit.
///

#include <iostream>

int SpaceCounter(double) {
static int called_times = 0;
called_times++;
return ((int)(called_times <= 3) * 4 * called_times) +
((int)(called_times > 3) * 8 * (called_times - 3));
}

int main(int argc, const char* argv[]) {
int a[3];
double b[3];

std::cout << SpaceCounter(a[0]);
std::cout << SpaceCounter(a[1]);
std::cout << SpaceCounter(a[2]);
std::cout << SpaceCounter(b[0]);
std::cout << SpaceCounter(b[1]);
std::cout << SpaceCounter(b[2]);

return 0;
}

Stage 5

Question 5.1

Code to meet the following functions.

The program lets the user enter two strings of letters, saves them in two character arrays, and then swaps the non-empty characters with the same subscript, and finally output the two new strings. Both strings of letters entered by the user are less than 20 (in upper and lower case) with an enter as the input of a string finishes, and do not contain any other characters. Additionally, there are restrictions:

  1. No libraries other than iostream are included.
  2. Only two character arrays with length of 20, one character variable and one character pointer are allowed to define and use.
  3. To the character variable above, only assignment operation is allowed. That is, no arithmetic or other operations (including compound assignment, self increase and self decrease, etc.).

Sample I/O

1
2
3
4
Input: ABCDEFGH
Input: abcde
Output: abcdeFGH
Output: ABCDE

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
///
/// @file 10-swap-two-strings.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 6, 2024
/// @version 0.2
/// @brief The use of swap method, pointers and addresses.
/// @note Do not include libraries other than "iostream".
/// ONLY ONE char, ONE char pointer, TWO char arrays are
/// allowed to be defined. The only char should ONLY be
/// assigned. DO NOT use it for calculation.
///

#include <iostream>

int main(int argc, char* argv[]) {
// Step 1: define the variables with initial values of NULL
char letter = 0, *counter = nullptr, a[20] = {0}, b[20] = {0};
// Step 2: input two strings of characters with an enter as finishing input
std::cout << "Input: ";
std::cin.getline(a, 20);
std::cout << "Input: ";
std::cin.getline(b, 20);
// Step 3: with the help of pointer counter, swap valid characters until a NULL is detected
for (counter = &a[0]; a[counter - &a[0]] != '\0' && b[counter - &a[0]] != '\0'; counter++) {
letter = a[counter - &a[0]];
a[counter - &a[0]] = b[counter - &a[0]];
b[counter - &a[0]] = letter;
}
// Step 4: output the result after swapping
std::cout << "Output: " << a << std::endl;
std::cout << "Output: " << b << std::endl;
return 0;
}

Question 5.2

Fill in the blank in main() and func() below so that the whole program can determine whether a positive integer input by the user is a palindrome number (i.e. a number reads the same backward as forward). Note that you can only add your code on the position of // BLANK FILLINGs, and user will just input a number and an enter when the input is completed. By the way, there are restrictions:

  1. No new variables, arrays or any other objects.
  2. No loops.
  3. No library functions called in the definition of func().
  4. The total of semicolons and commas of your fillings is no more than 10.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <cstring>

using namespace std;

bool func(char array[], int len);

int main() {
char ch[20];
bool result;

cout<< "Input: ";
cin >> ch;
// Write your own code below.
return 0;
}
bool func(char array[], int len) {
// Write your own code below.
}

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
///
/// @file 11-palindromic-number.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 6, 2024
/// @version 0.2
/// @brief The use of recursive function calls.
/// @note No more than 10 semicolons(;) and commas(,) total
/// in your self-written code.
/// You can ONLY write your own code in the areas given
/// (See comments in the functions).
/// DO NOT call library functions in function "func".
/// DO NOT use loops. NO MORE self-defined objects.
///

#include <iostream>
#include <cstring>

using namespace std;

bool func(char array[], int len);

int main() {
char ch[20];
bool result;

cout<< "Input: ";
cin >> ch;

// Write your own code below.
// Note that "result" given by the question is useless. Just let the return value of "func()" be the judgement expression.
if (func(ch, strlen(ch)))
cout << "Output: Yes" << endl;
else
cout << "Output: No" << endl;
// 2 semicolons(;) & 1 comma(,)
return 0;
}

bool func(char array[], int len) {
// Write your own code below.
if (len == 1 || len == 0)
return true;
if (array[0] == array[len - 1])
if(func(array + 1, len - 2))
return true;
return false;
// 3 semicolons(;) & 1 comma(,)
}
// TOTAL 5 SEMICOLONS AND 2 COMMAS

Stage 6

Question 6.1

Code to meet the following needs.

The user will enter a line of sentence with at most 10 words, 100 characters. Count and output how many words the sentence has. Then the user will input a string of numbers to express the new sequence of the words. Output the sentence with the new sequence of the words. Additionally, all the arrays you are going to use should be defined by new. Note that the sentence user inputs contains letters and spaces only and no spaces at the end of the sentence, but an enter; and the string of numbers is guaranteed to express a right sequence of words in the sentence, i. e. no exceptional case.

Sample I/O

1
2
3
4
Input: Welcome to my hometown
Output: 4
Input: 1302
Output: to hometown Welcome my
1
2
3
4
Input: This is a good day to work
Output: 7
Input: 6543210
Output: work to day good a is This

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
///
/// @file 12-new-rearrange-words.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 6, 2024
/// @version 0.2
/// @brief The use of standard library and ADT strings.
/// @note The user just input no more than 100 characters
/// and each word has no more than 10 characters.
///

#include <iostream>

int main(int argc, const char* argv[]) {
// Step 1: input a sentence without a full stop(.)
std::string input;
std::cout << "Input: ";
std::getline(std::cin, input);
// The last element of a char string is nullptr.
char* sentence = new char[input.length() + 1];
// Copy string to the char array "sentence".
input.copy(sentence, input.length() + 1, 0);
// Step 2: count the words input and output
char key = ' ';
int counter = 0;
for (int i = 0; sentence[i] != '\0'; i++) {
if (key == ' ' && sentence[i] != ' ')
counter++;
key = sentence[i];
}
std::cout << "Output: " << counter << std::endl;
// Step 3: calculate the length of each word and store in the array
int* length = new int[counter];
for (int i = -1, j = 0; i < counter && key != '\0'; j++) {
if (key == ' ' && sentence[j] != ' ')
i++;
while (sentence[j] != '\0')
if (sentence[j] != ' ') {
length[i]++;
j++;
}
else
break;
key = sentence[j];
}
// Step 4: split each word and store in the 2-d array
char** words = new char* [counter];
for (int i = 0; i < counter; i++)
words[i] = new char[length[i]];
for (int i = 0, k = 0; i < counter; i++) {
for (int j = 0; j < length[i]; j++, k++)
words[i][j] = sentence[k];
while (sentence[k] == ' ')
k++;
}
// Release the heap memory of "sentence".
delete [] sentence;
// Step 5: input the new order of the words
char* order = new char[counter];
std::cout << "Input: ";
for (int i = 0; i < counter; i++)
std::cin >> order[i];
// Convert char array to int array.
int* result = new int[counter];
for (int i = 0; i < counter; i++)
result[i] = order[i] - '0';
std::cout << "Output: ";
for (int i = 0; i < counter; i++) {
for (int j = 0; j < length[result[i]]; j++)
std::cout << words[result[i]][j];
std::cout << ' ';
}
// Release the heap memory of "length", "words", "order", "result".
for (int i = 0; i < counter; i++)
delete [] words[i];
delete [] length, words, order, result;
return 0;
}

Question 6.2

Fill in the blank with restrictions below so that the program will output three numbers, the first of which is the ones place of x minus y, the second of which is triple x, and the third of which is double y, where x is the first number input and y the second. The restrictions are described in the annotations of the code. Note that there needs a space between the output numbers, as the sample shows, and do not add or modify anything except where the annotations are.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;

// Fill two lines of code below.
// Fill two lines of code above.
int myfun(int *a, int *b);

int main(void) {
int x, y;
cout << "Input: ";
cin >> x >> y;
cout << "Output: ";
cout << myfun(x, y);
cout << x << ' ' << y;
return 0;
}
int myfun(int *a, int *b) {
int c = *a - *b;
*a *= 2;
*b *= 3;
return c;
}
// Define only one function here. The function body has only 2 lines (at most 2 semicolons) of code and no names of arrays.

Sample I/O

1
2
Input: 18 5
Output: 3 54 10

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
///
/// @file 13-pointers-and-overload.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 6, 2024
/// @version 0.2
/// @brief The use of standard library and reference.
/// @note The user just input no more than 100 characters
/// and each word has no more than 10 characters.
///

#include <iostream>
using namespace std;

// Fill two lines of code below.
#define ABS_INT(integer) ((integer >= 0)? integer : -integer)
string myfun(int &a, int &b);
// Fill two lines of code above.
int myfun(int *a, int *b);

int main(int argc, char* argv[]) {
int x, y;
cout << "Input: ";
cin >> x >> y;
cout << "Output: ";
cout << myfun(x, y);
cout << x << ' ' << y;
return 0;
}

int myfun(int *a, int *b) {
int c = *a - *b;
*a *= 2;
*b *= 3;
return c;
}

// Define a function below.
/// @note This function must contain NO MORE THAN 2 semicolons(;)
/// and NO commas(,) unless it is for function parameters.
string myfun(int &a, int &b) {
int first = myfun(&b, &a);
return to_string(ABS_INT(first) % 10) + string(" ");
}

Stage 7

Question 7.1

Write out the declaration and definitions of two functions funA() and funB() below so that funA() has the access to an inputted string from pointer p and funB() turns all the numbers of the string into '0' and outputs the string. You need to make sure that no memory leak happens at the end of each program block, and the program has correct newlines as the sample below shows. Note that the input by the user is a string of letters and numbers, less than 8 characters, and an enter as the input finishes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <cstring>
using namespace std;

// Declare two functions below.

int main() {
char a[10], b[10];
for (int i=0; i<2; ++i) {
char **p;
cout << "Input: ";
cin >> a;
funA(p) = a;
cout << "Output: ";
cout << funB(b, *p);
}
return 0;
}

// Define two functions below.

Sample I/O

1
2
Input: ab2G49N3
Output: ab0G00N0
1
2
Input: 0Mx2uW
Output: 0Mx0uW

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
///
/// @file 13-pointers-and-overload
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 8, 2024
/// @version 0.2
/// @brief The use of function, reference and pointers.
/// @note Please ensure no memory leaks during runtime.
///

#include <iostream>
#include <cstring>
using namespace std;

// Declare two functions below.
char* &funA(char** &);
char* funB(char*, char* &);

int main() {
char a[10], b[10];
for (int i=0; i<2; ++i) {
char **p;
cout << "Input: ";
cin >> a;
funA(p) = a;
cout << "Output: ";
cout << funB(b, *p);
}
return 0;
}

// Define two functions below.
/// @brief This function is to create a char pointer so
/// that the reference type matches the RHS.
/// @note This function is used as left value,
/// so the return type must be reference.
char* &funA(char** &p) {
p = new char*;
return *p;
}

/// @note The string must have no more than 8 chars.
char* funB(char* invalid, char* &p) {
short length = strlen(p);
if (length > 8) {
cout << "PANIC: illegal input" << endl;
exit(-1);
}
for (short i = 0; i < length; i++)
if (p[i] - '0' > 0 && p[i] - '0' <= 9)
p[i] = '0';
p[length] = '\n';
p[length + 1]= '\0';
return p;
}

Question 7.2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <iostream>
#define HEAL_VALID 20
#define HEAL_EFFECT 10
using namespace std;

struct Actor {
// Define something below.
};

Actor &GetPlayer(char[], int);
Actor &GetEnemy(int);
void Action(Actor&, Actor&, int);

int main() {
char name[10];
int money, act;
cout << "What's your name? (No more than 9 letters) ";
cin >> name;
cout << "How much will you pay for the game? $";
cin >> money;
Actor &player = GetPlayer(name, money);
Actor &enemy = GetEnemy(money);
cout << "===== " << player.name << " vs " << enemy.name << " =====" << endl;
if (money < 1) {
cout << "You Lose!" << endl;
return 0;
}
for (int i = 1; i <= 10; ++i) {
cout << "Round " << i << endl;
// Write some code below.
Action(player, enemy, act);
if (enemy.hp < 10 && enemy.heal)
act = 2;
else
act = 1;
Action(enemy, player, act);
if (player.hp > 0 && enemy.hp <= 0) {
cout << "You Win!" << endl;
return 0;
}
else if (enemy.hp > 0 && player.hp <= 0) {
cout << "You Lose!" << endl;
return 0;
}
else if (player.hp <= 0 && enemy.hp <= 0) {
cout << "End of Game with Draw." << endl;
return 0;
}
cout << player.name << "'s remaining HP: " << player.hp << endl;
cout << enemy.name << "'s remaining HP: " << enemy.hp << endl;
cout << "------------------------------------------" << endl;
}
cout << "End of Game with Draw." << endl;
return 0;
}

Actor &GetPlayer(char name[], int m) {
Actor *player = new Actor({name, m, m / 2, m / 3, m >= HEAL_VALID});
// Write some code below.
}

Actor &GetEnemy(int m) {
Actor *enemy;
int choice;
cout << "Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): ";
cin >> choice;
if (choice)
enemy = new Actor({(char*)"Slime", 20 + m / 5, 8 + m / 6, 7 + m / 6, true});
else
enemy = new Actor({(char*)"Wolf", 25 + m / 4, 9 + m / 6, 6 + m / 6, false});
// Write some code below.
}

void Action(Actor &user, Actor &target, int act) {
if (act == 1) {
cout << user.name << " attacks " << target.name << "!" << endl;
int damage = user.atk - target.def;
if (damage < 0)
damage = 0;
target.hp -= damage;
}
else if (act == 2) {
cout << user.name << " does self-healing!" << endl;
user.hp += HEAL_EFFECT;
}
else
cout << user.name << " is waiting..." << endl;
}

Code to complete a simple and crude game starting with topping up. The features of the game:

  1. The player chooses the action of every round, 1 for attack, 2 for heal, 3 for wait.
  2. The heal is available when the player tops up at least $20, that is, heal is hidden when a lower money is topped up.
  3. The whole game plays like the samples shown below.

Note that you can only add your code to complete the game code where the annotations are, and do not worry about wrong inputs from the player. By the way, when you finish this game, you can consider expanding more features like new actions (e.g. tool, escape), new enemies, or more attack force when the enemy has a low HP, etc.

Sample I/O

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
What's your name? (No more than 9 letters) Jack
How much will you pay for the game? $30
Welcome to this game, Jack!
Your status: HP30, ATK15, DEF10
You can attack the enemy and heal yourself.
Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): 0
Your enemy Wolf: HP32, ATK14, DEF11
===== Jack vs Wolf =====
Round 1
Jack's act (1-attack; 2-heal; otherwise-wait): 1
Jack attacks Wolf!
Wolf attacks Jack!
Jack's remaining HP: 26
Wolf's remaining HP: 28
---------------------
Round 2
Jack's act (1-attack; 2-heal; otherwise-wait): 1
Jack attacks Wolf!
Wolf attacks Jack!
Jack's remaining HP: 22
Wolf's remaining HP: 24
---------------------
(the player enters "1" over Round 3-6, shorten here)
---------------------
Round 7
Jack's act (1-attack; 2-heal; otherwise-wait): 1
Jack attacks Wolf!
Wolf attacks Jack!
Jack's remaining HP: 2
Wolf's remaining HP: 4
---------------------
Round 8
Jack's act (1-attack; 2-heal; otherwise-wait): 2
Jack does self-healing!
Wolf attacks Jack!
Jack's remaining HP: 8
Wolf's remaining HP: 4
---------------------
Round 9
Jack's act (1-attack; 2-heal; otherwise-wait): 1
Jack attacks Wolf!
Wolf attacks Jack!
You Win!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
What's your name? (No more than 9 letters) Tom
How much will you pay for the game? $15
Welcome to this game, Tom!
Your status: HP15, ATK7, DEF5
You can attack the enemy but not heal yourself.
Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): 0
Your enemy Wolf: HP28, ATK11, DEF8
===== Tom vs Wolf =====
Round 1
Tom's act (1-attack; otherwise-wait): 1
Tom attacks Wolf!
Wolf attacks Tom!
Tom's remaining HP: 9
Wolf's remaining HP: 28
---------------------
Round 2
Tom's act (1-attack; otherwise-wait): 2
Tom is waiting...
Wolf attacks Tom!
Tom's remaining HP: 3
Wolf's remaining HP: 28
---------------------
Round 3
Tom's act (1-attack; otherwise-wait): 1
Tom attacks Wolf!
Wolf attacks Tom!
You Lose!

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
///
/// @file 15-games-class-members.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 8, 2024
/// @version 0.2
/// @brief The use of class.
///

#include <iostream>
#define HEAL_VALID 20
#define HEAL_EFFECT 10
using namespace std;

struct Actor {
// Define something below.
char* name;
int hp, atk, def;
bool heal;
};

Actor &GetPlayer(char[], int);
Actor &GetEnemy(int);
void Action(Actor&, Actor&, int);

int main() {
char name[10];
int money, act;
cout << "What's your name? (No more than 9 letters) ";
cin >> name;
cout << "How much will you pay for the game? $";
cin >> money;
Actor &player = GetPlayer(name, money);
Actor &enemy = GetEnemy(money);
cout << "===== " << player.name << " vs " << enemy.name << " =====" << endl;
if (money < 1) {
cout << "You Lose!" << endl;
return 0;
}
for (int i = 1; i <= 10; ++i) {
cout << "Round " << i << endl;
// Write some code below.
cout << player.name << (player.heal ? "'s act (1-attack; 2-heal; otherwise-wait): " : "'s act (1-attack; otherwise-wait): ");
cin >> act;
if (!player.heal && act == 2)
act++;
Action(player, enemy, act);
if (enemy.hp < 10 && enemy.heal)
act = 2;
else
act = 1;
Action(enemy, player, act);
if (player.hp > 0 && enemy.hp <= 0) {
cout << "You Win!" << endl;
return 0;
}
else if (enemy.hp > 0 && player.hp <= 0) {
cout << "You Looose!" << endl;
return 0;
}
else if (player.hp <= 0 && enemy.hp <= 0) {
cout << "End of Game with Draw." << endl;
return 0;
}
cout << player.name << "'s remaining HP: " << player.hp << endl;
cout << enemy.name << "'s remaining HP: " << enemy.hp << endl;
cout << "------------------------------------------" << endl;
}
cout << "End of Game with Draw." << endl; // draw: v. & n. 平局
return 0;
}

Actor &GetPlayer(char name[], int m) {
Actor *player = new Actor({name, m, m / 2, m / 3, m >= HEAL_VALID});
// Write some code below.
cout << "Welcome to this game, " << player -> name << "!\n";
cout << "Your status: HP" << player -> hp << ", ATK" << player -> atk << ", DEF" << player -> def << '\n';
cout << (player -> heal ? "You can attack the enemy and heal yourself." : "You can attack the enemy but not heal yourself.") << endl;
return *player;
}

Actor &GetEnemy(int m) {
Actor *enemy;
int choice;
cout << "Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): ";
cin >> choice;
if (choice)
enemy = new Actor({(char*)"Slime", 20 + m / 5, 8 + m / 6, 7 + m / 6, true});
else
enemy = new Actor({(char*)"Wolf", 25 + m / 4, 9 + m / 6, 6 + m / 6, false});
// Write some code below.
cout << "Your enemy " << enemy -> name << ": HP" << enemy -> hp << ", ATK" << enemy -> atk << ", DEF" << enemy -> def << endl;
return *enemy;
}

void Action(Actor &user, Actor &target, int act) {
if (act == 1) {
cout << user.name << " attacks " << target.name << "!" << endl;
int damage = user.atk - target.def;
if (damage < 0)
damage = 0;
target.hp -= damage;
}
else if (act == 2) {
cout << user.name << " does self-healing!" << endl;
user.hp += HEAL_EFFECT;
}
else
cout << user.name << " is waiting..." << endl;
}

Stage 8

Question 8.1

As the code shown below, write your declaration and definition of function myfun() and fill in the blanks of main(), so that the program conducts the matrix multiplication of A\boldsymbol{A} and B\boldsymbol{B}, where A\boldsymbol{A} is a 3×n3\times n matrix and B\boldsymbol{B} is an n×3n\times3 matrix. Additionally, one of A\boldsymbol{A} and B\boldsymbol{B} need to be stored by a pointer to array and the other by an array of pointers, and all the elements of B\boldsymbol{B} are continuous in the memory. Note that the output format should be identical as the sample shows.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;

// Declare function "myfun" below.

int main() {
int n;
cout << "Input n: ";
cin >> n;
cout << "Input A: ";
// Write some code below.

cout << "Input B: ";
// Write some code below.

cout << "Output:\n";
for(int i = 0; i < 3; ++i)
myfun(A[i], B, n);
// Write some code below.
return 0;
}

// Define function "myfun" below.

Sample I/O

1
2
3
4
5
6
7
Input n: 2
Input A: 1 2 3 4 5 6
Input B: 2 3 4 5 6 7
Output:
12 15 18
26 33 40
40 51 62

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
///
/// @file 16-matrix-multiplication.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 8, 2024
/// @version 0.2
/// @brief The use of pointers and matrix multiplication.
///

#include <iostream>
using namespace std;

// Declare function "myfun" below.
void myfun(int*, int*, int);

int main() {
int n;
cout << "Input n: ";
cin >> n;
cout << "Input A: ";
// Write some code below.
// A is an array of (int) pointers.
int* A[3];
for (int i = 0; i < 3; i++)
A[i] = new int[n];
for (int i = 0; i < 3; i++)
for (int j = 0; j < n; j++)
cin >> A[i][j];
cout << "Input B: ";
// Write some code below.
// B is a pointer to a dynamic 1-d array.
int* B = new int[n * 3];
for (int i = 0; i < n * 3; i++)
cin >> B[i];
cout << "Output:\n";
for(int i = 0; i < 3; ++i)
myfun(A[i], B, n);
delete [] B;
return 0;
}
// Define function "myfun" below.
void myfun(int* a, int* b, int n) {
for (int i = 0; i < 3; i++) {
int sum = 0;
for (int j = 0; j < n; j++)
sum += a[j] * b[i + j * 3];
cout << sum << ' ';
}
cout << endl;
}

Question 8.2

Add one word to each of the two source files below so that the project made up of the two can be compiled to a runnable program.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
///// main.cpp /////
#include <iostream>
using namespace std;

int myfun(int);
int yourfun(int);

int main() {
int n;
cout << "Input: ";
cin >> n;
cout << "Output: ";
cout << myfun(n) << endl;
return 0;
}

int myfun(int n) {
int x;
return yourfun(n + x);
}
1
2
3
4
5
6
7
8
9
10
///// library.cpp /////
int x = 10;

int myfun(int n) {
return n * 2;
}

int yourfun(int y) {
return myfun(y);
}

Sample I/O

1
2
Input: 6
Output: 32
1
2
Input: 13
Output: 46

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
///
/// @file 17-another-source-main.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 8, 2024
/// @version 0.2
/// @brief The use of "extern" keyword.
///

#include <iostream>
using namespace std;

int myfun(int);
int yourfun(int);

int main() {
int n;
cout << "Input: ";
cin >> n;
cout << "Output: ";
cout << myfun(n) << endl;
return 0;
}

int myfun(int n) {
extern int x; // Add "extern" to import global x = 10 from another cpp file. Only establish the aim in this way.
return yourfun(n + x);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
///
/// @file 17-another-source-library.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 8, 2024
/// @version 0.2
/// @brief The use of static functions.
///

int x = 10;

/// @note Add "static" so that the function is only available to this file.
static int myfun(int n) {
return n * 2;
}

int yourfun(int y) {
return myfun(y);
}

Stage 9

The Requirements

Please fill in all the blanks in the code below. The I/O samples are like those in Stage 7. The main difference from Stage 7 is the total budget, which turns to $50, and the player can buy a sword for $10. Note that you should not modify any code other than where the blanks are, and don’t worry about wrong inputs from the player. By the way, after finishing this stage, you can consider adding some new enemies, new weapons or something else you like to the game.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>

#define HEAL_VALID 20
#define HEAL_EFFECT 10
#define TOTAL_MONEY 50

using namespace std;

class Weapon {
// BLANK FILLING #1
const int effect;
const int price;
};

class Actor {
char *name;
int hp;
int atk;
int def;
bool heal;
bool isPlayer;
// BLANK FILLING #2
void equip(Weapon &w) {
atk += w.effect;
};
char *get_name() {
return name;
};
int get_hp() {
return hp;
};
};

int main() {
char name[10];
int money, enemy_choice, weapon_choice;
Weapon sword(10, 10);
cout << "What's your name? (No more than 9 letters) ";
cin >> name;
cout << "You have $" << TOTAL_MONEY << " in total." << endl;
cout << "How much will you pay for your basic attributes? $";
cin >> money;
Actor player(name, money);
cout << "---------------------" << endl;
cout << "Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): ";
cin >> enemy_choice;
Actor enemy(enemy_choice, money);
cout << "---------------------" << endl;
cout << "You have $" << TOTAL_MONEY - money << " left." << endl;
if (TOTAL_MONEY - money >= sword.price) {
cout << "If you want to spend $10 to buy a sword, input 1: ";
cin >> weapon_choice;
if (weapon_choice == 1) {
cout << name << " has a sword now! ATK+" << sword.effect << "!" << endl;
player.equip(sword);
} else
cout << name << " has no sword." << endl;
}
cout << "===== " << player.get_name() << " vs " << enemy.get_name() << " =====" << endl;
if (money < 1) {
cout << "You Looose!" << endl;
return 0;
}
for (int i = 1; i <= 10; ++i) {
cout << "Round " << i << endl;
player.Action(enemy);
enemy.Action(player);
cout << player.get_name() << "'s remaining HP: " << player.get_hp() << endl;
cout << enemy.get_name() << "'s remaining HP: " << enemy.get_hp() << endl;
cout << "---------------------" << endl;
// BLANK FILLING #3
// The code needed here is to determine whether the fight is over and the victory or defeat information is the same as that in Stage 7.
}
cout << "End of Game with Draw." << endl;
return 0;
}

// BLANK FILLING #4
/* A HEAD OF A FUNCTION()*/ {
// BLANK FILLING #5
// The code needed here is to set the basic attributes of the player, show welcome and status message like those in Stage 7
cout << "You can act with 1 to attack the enemy, " << (heal ? "2 to heal yourself, " : "") << "and otherwise wait." << endl;
}

// BLANK FILLING #6
// The code needed here is the definition of a function that the options of enemy, the attributives of the enemy and the output of the information of the enemy are the same as those in Stage 7.

// BLANK FILLING #7
// The code needed here is the definition of a function that the options for the player, the actions of the enemy, the changes of HP of both sides and the output messages are the same as those in Stage 7.

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
///
/// @file 18-game-class-constructor.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 9, 2024
/// @version 0.2
/// @brief The use of class.
/// @note Do not modify or write more code unless allowed in
/// the limited places (see comments).
///

#include <iostream>

#define HEAL_VALID 20
#define HEAL_EFFECT 10
#define TOTAL_MONEY 50

using namespace std;

class Weapon {
// Write some code below.
public:
Weapon(int a, int b): effect(a), price(b) {}
// Write some code above.
const int effect;
const int price;
};

class Actor {
char *name;
int hp;
int atk;
int def;
bool heal;
bool isPlayer;
// Write some code below.
public:
Actor(char[], int);
Actor(int, int);
void Action(Actor &);
// Write some code above.
void equip(Weapon &w) {
atk += w.effect;
};
char *get_name() {
return name;
};
int get_hp() {
return hp;
};
};

int main() {
char name[10];
int money, enemy_choice, weapon_choice;
Weapon sword(10, 10);
cout << "What's your name? (No more than 9 letters) ";
cin >> name;
cout << "You have $" << TOTAL_MONEY << " in total." << endl;
cout << "How much will you pay for your basic attributes? $";
cin >> money;
Actor player(name, money);
cout << "---------------------" << endl;
cout << "Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): ";
cin >> enemy_choice;
Actor enemy(enemy_choice, money);
cout << "---------------------" << endl;
cout << "You have $" << TOTAL_MONEY - money << " left." << endl;
if (TOTAL_MONEY - money >= sword.price) {
cout << "If you want to spend $10 to buy a sword, input 1: ";
cin >> weapon_choice;
if (weapon_choice == 1) {
cout << name << " has a sword now! ATK+" << sword.effect << "!" << endl;
player.equip(sword);
} else
cout << name << " has no sword." << endl;
}
cout << "===== " << player.get_name() << " vs " << enemy.get_name() << " =====" << endl;
if (money < 1) {
cout << "You Looose!" << endl;
return 0;
}
for (int i = 1; i <= 10; ++i) {
cout << "Round " << i << endl;
player.Action(enemy);
enemy.Action(player);
cout << player.get_name() << "'s remaining HP: " << player.get_hp() << endl;
cout << enemy.get_name() << "'s remaining HP: " << enemy.get_hp() << endl;
cout << "---------------------" << endl;
// Write some code below so that the output is the same as in the file "15-game-class-members.cc"
if (player.get_hp() > 0 && enemy.get_hp() <= 0) {
cout << "You Win!" << endl;
return 0;
}
else if (enemy.get_hp() > 0 && player.get_hp() <= 0) {
cout << "You Looose!" << endl;
return 0;
}
else if (player.get_hp() <= 0 && enemy.get_hp() <= 0) {
cout << "End of Game with Draw." << endl;
return 0;
}
}
cout << "End of Game with Draw." << endl;
return 0;
}

// Write some code below so that the input/output is the same as in the file "15-game-class-members.cc"
Actor::Actor(char a[], int b): name(a), hp(b), atk(b / 2), def(b / 3), heal(b >= HEAL_VALID), isPlayer(true) {
cout << "Welcome to this game, " << name << "!\n";
cout << "Your status: HP" << hp << ", ATK" << atk << ", DEF" << def << '\n';
cout << "You can attack the enemy " << (heal ? "and" : "but not") << " heal yourself." << endl;
cout << "You can act with 1 to attack the enemy, " << (heal ? "2 to heal yourself, " : "") << "and otherwise wait." << endl;
}
// Define a function below so that the attributes behave the same as in the file "15-game-class-members.cc"
Actor::Actor(int a, int b): heal(a), isPlayer(false) {
if (heal) {
name = (char*)"Slime";
hp = 20 + b / 5;
atk = 8 + b / 6;
def = 7 + b / 6;
}
else {
name = (char*)"Wolf";
hp = 25 + b / 4;
atk = 9 + b / 6;
def = 6 + b / 6;
}
cout << "Your enemy " << name << ": HP" << hp << ", ATK" << atk << ", DEF" << def << endl;
}
// Define a function below so that the attributes behave the same as in the file "15-game-class-members.cc"
void Actor::Action(Actor &entity) {
int act;
if (!entity.isPlayer) {
cout << this -> name << "'s act (1-attack; " << (this -> heal ? "2-heal; " : "") << "otherwise-wait): " << flush;
cin >> act;
if (!(this -> heal) && act == 2)
act++;
}
else {
if (this -> hp < 10 && this -> heal)
act = 2;
else
act = 1;
}
if (act == 1) {
cout << this -> name << " attacks " << entity.name << "!" << endl;
int damage = this -> atk - entity.def;
if (damage < 0)
damage = 0;
entity.hp -= damage;
}
else if (act == 2) {
cout << this -> name << " does self-healing!" << endl;
this -> hp += HEAL_EFFECT;
}
else
cout << this -> name << " is waiting..." << endl;
}

Stage 10

The Requirements

Please fill in all the blanks in the code below.

The program simulates a cell culture environment where resource is initially 500.

Class Cell contains 2 private data members and 8 public member functions, no public data members or private member functions. The 2 private data members are size and resource, both of which are integers. The names of the 8 member functions are Cell(), ~Cell(), grow(), eat(), get_size(), get_resource(). You may notice that there are 8 functions but 6 names. init_size input from the user is in [1,100][1,100].

In each cycle of while, the following operations are performed: the initial cell and each ordinary cell that has been born will grow once; the growth of an ordinary cell will make its size increase by 1, while the resource in the whole environment decrease by 1; the growth of the initial cell will not change its size, but will still make the resource decrease by 1; if the size of an ordinary cell is greater than 5, then it will create a new ordinary cell, which is half the size of the original cell (rounding off the decimal), and the resource in the environment will be reduced by the size of the new cell.

Before the end of each cycle of while, if the size of the largest cell in the environment is greater than 10, the initial cell will eat it and increase the resource in the environment by an amount equal to the size of the eaten cell.

When the resource in the environment is reduced to 0 or negative, or when the 100th ordinary cell is created, the while cycle should be interrupted.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using namespace std;

class Cell {
// BLANK FILLING #1
};

int main() {
int init_size, id = 1, eaten = 0, i, size, eat;
Cell *cells[100] = {0};
cout << "Initial Cell Size: ";
cin >> init_size;
const Cell *init_cell = new const Cell(init_size);
cout << "Initial Cell is born, remaining resource = " << Cell::get_resource() << endl;

cells[0] = new Cell(*init_cell);
cout << "Cell 0 is born, remaining resource = " << Cell::get_resource() << endl;
while (true) {
// BLANK FILLING #2
}

return 0;
}

// BLANK FILLING #3
// The code needed here is the implementation of class "Cell"

Sample I/O

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Initial Cell Size: 10
Initial Cell is born, remaining resource = 490
Cell 0 is born, remaining resource = 485
Initial Cell grows, remaining resource = 484
Cell 0 grows, remaining resource = 483
Cell 1 is born, remaining resource = 480
Initial Cell grows, remaining resource = 479
Cell 0 grows, remaining resource = 478
Cell 2 is born, remaining resource = 475
Cell 1 grows, remaining resource = 474
(Many rows are left out.)
Cell 15 grows, remaining resource = 10
Cell 94 is born, remaining resource = 6
Cell 16 grows, remaining resource = 5
Cell 95 is born, remaining resource = 1
Cell 17 grows, remaining resource = 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Initial Cell Size: 100
Initial Cell is born, remaining resource = 400
Cell 0 is born, remaining resource = 350
Initial Cell grows, remaining resource = 349
Cell 0 grows, remaining resource = 348
Cell 1 is born, remaining resource = 323
Cell 0 is eaten, remaining resource = 374
Initial Cell grows, remaining resource = 373
Cell 1 grows, remaining resource = 372
Cell 2 is born, remaining resource = 359
Cell 1 is eaten, remaining resource = 385
(Many rows are left out.)
Cell 16 grows, remaining resource = 14
Cell 79 is born, remaining resource = 10
Cell 17 grows, remaining resource = 9
Cell 80 is born, remaining resource = 5
Cell 18 grows, remaining resource = 4
Cell 81 is born, remaining resource = 0

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <iostream>
using namespace std;

class Cell {
// BLANK FILLING #1
// Step 1: declare essential member variables
private:
int size;
static int resource;
// Step 2: declare constructors, destructor and member operations
public:
Cell(int);
Cell(const Cell&);
~Cell();
static int get_resource();
int get_size();
void grow() const;
void grow(int);
void eat(int, Cell*&) const;
};

int main() {
int init_size, id = 1, eaten = 0, i, size, eat;
Cell *cells[100] = {0};
cout << "Initial Cell Size: ";
cin >> init_size;
const Cell *init_cell = new const Cell(init_size);
cout << "Initial Cell is born, remaining resource = " << Cell::get_resource() << endl;

cells[0] = new Cell(*init_cell);
cout << "Cell 0 is born, remaining resource = " << Cell::get_resource() << endl;
while (true) {
// BLANK FILLING #2
// Step 3: guess the code to be written from the output demonstration
// First, grow the "init_cell".
init_cell -> grow();
// Then, let other cells grow if the conditions meet.
for (int i = 0, stop = id; i < stop && Cell::get_resource() > 0 && id <= 100; i++)
if (cells[i]) {
cells[i] -> grow(i);
// Spawn more normal cells if the resources are enough.
if (cells[i] -> get_size() > 5 && Cell::get_resource() >= cells[i] -> get_size() / 2) {
cells[id] = new Cell(cells[i] -> get_size() / 2);
cout << "Cell " << id++ << " is born, remaining resource = " << Cell::get_resource() << endl;
}
}
// Choose one with the biggest size from normal cells.
for (i = 0, size = 0; i < id; i++)
if (cells[i])
if (cells[i] -> get_size() > size) {
size = cells[i] -> get_size();
eat = i;
}
// init_cell would eat cells if the conditions meet.
if (size > 10 && Cell::get_resource() > 0)
init_cell -> eat(eat, cells[eat]);
// Finally, recycle all memory space and break the loop if the conditions meet.
if (Cell::get_resource() <= 0 || id > 100) {
delete init_cell;
for (int i = 0; i < id && cells[i]; i++)
delete cells[i];
break;
}
}

return 0;
}

// BLANK FILLING #3
// The code needed here is the implementation of class "Cell"
// Step 4: initialize static class objects
int Cell::resource = 500;

// Step 5: define all the functions of the class

/// @brief Get the private member "resource" of the class.
int Cell::get_resource() {
return resource;
}

/// @brief Get the private member "resource" of the class (normal cells only).
int Cell::get_size() {
return size;
}

/// @brief Constructor of new normal cells.
Cell::Cell(int spawnSize) {
if (spawnSize < 1 || spawnSize > 100) {
cout << "Cell initialization failed." << endl;
return;
}
size = spawnSize;
resource -= spawnSize;
}

/// @brief Constructor of the initial cell (Cell #0).
Cell::Cell(const Cell& initialCell) {
size = initialCell.size / 2;
resource -= initialCell.size / 2;
}

/// @brief Let the initial cell grow.
void Cell::grow() const {
resource--;
cout << "Initial Cell grows, remaining resource = " << resource << endl;
}

/// @brief Let normal cells grow.
void Cell::grow(int id) {
size++;
resource--;
cout << "Cell " << id << " grows, remaining resource = " << resource << endl;
}

/// @brief Let the initial cell eat.
void Cell::eat(int id, Cell*& CellToEat) const {
delete CellToEat;
CellToEat = nullptr;
cout << "Cell " << id << " is eaten, remaining resource = " << resource << endl;
}

/// @brief Let resources more if a cell dies.
Cell::~Cell() {
resource += size;
}

Stage 11

The Requirements

Please fill in all the blanks in the code below so that the program runs the same as in Stage 10.

No global variables or functions are defined except for defining the derived class of Cell and implementing these two classes and their operator overloaded functions. The derived class of Cell contains two new private data members and no public data members. The two private data members are id and counter, both integers. The definition of the derived class of Cell only contains at most three member functions.

Note that operators that need to be overloaded have and only have =, << and >>.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
using namespace std;

class Cell {
friend istream &operator>>(istream &, Cell &);
protected:
int size;
static int resource;
public:
int get_size() const {
return size;
}
bool grow();
};

// BLANK FILLING #1
// The code needed here is the definition of a derived class of "Cell".

int main() {
Cell init_cell;
NewCell cells[100];
int born = 1, eaten = 0, maxsize;

cout << "Initial Cell Size: ";
cin >> init_cell;
if (cells[0] = init_cell)
return 0;

while (true) {
if (init_cell.grow())
return 0;
int thisround = born;
for (int i = 0; i < thisround; ++i) {
if (cells[i].get_size() == 0)
continue;
if (cells[i].grow())
return 0;
if (cells[i].get_size() > 5) {
if (cells[born] = cells[i])
return 0;
if (cells[born].get_size() > cells[eaten].get_size())
eaten = born;
born++;
if (born >= 100)
return 0;
}
}
if (cells[eaten].get_size() > 10) {
cout << cells[eaten];
eaten = 0, maxsize = 0;
for (int i = 0; i < born; ++i)
if (cells[i].get_size() > maxsize) {
maxsize = cells[i].get_size();
eaten = i;
}
}
}
return 0;
}

// BLANK FILLING #2
// The code needed here is to implement the two classes and their definitions of the overloaded operators.

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
///
/// @file 20-operator-overloads.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 11, 2024
/// @version 0.2
/// @brief The use of class operators.
/// @note Do not moidify or write more code unless allowed in
/// the limited places (see comments).
///


#include <iostream>
using namespace std;

class Cell {
friend istream &operator>>(istream &, Cell &);
protected:
int size;
static int resource;
public:
int get_size() const {
return size;
}
bool grow();
};

// BLANK FILLING #1 (Define a new class to derive class "Cell")
// Do not define other global variables or functions unless they are operator overloads of the classes.
// The class to derive "Cell" has 2 new private data members and no public data members.
// The 2 private members must be called "id" and "counter", both are int.
// The class to derive "Cell" has at most 3 member functions.
// The operators needed to be overloaded are only = << and >>
class NewCell: public Cell {
friend ostream& operator<<(ostream& output, NewCell& target);
// Step 1: declare the private integers
private:
int id;
static int counter;
// Step 2: declare "operator=" overloads and "grow" method
public:
bool operator=(Cell& source);
bool operator=(NewCell& source);
bool grow(void);
};
// Write some code above.

int main() {
Cell init_cell;
NewCell cells[100];
int born = 1, eaten = 0, maxsize;

cout << "Initial Cell Size: ";
cin >> init_cell;
if (cells[0] = init_cell)
return 0;

while (true) {
if (init_cell.grow())
return 0;
int thisround = born;
for (int i = 0; i < thisround; ++i) {
if (cells[i].get_size() == 0)
continue;
if (cells[i].grow())
return 0;
if (cells[i].get_size() > 5) {
if (cells[born] = cells[i])
return 0;
if (cells[born].get_size() > cells[eaten].get_size())
eaten = born;
born++;
if (born >= 100)
return 0;
}
}
if (cells[eaten].get_size() > 10) {
cout << cells[eaten];
eaten = 0, maxsize = 0;
for (int i = 0; i < born; ++i)
if (cells[i].get_size() > maxsize) {
maxsize = cells[i].get_size();
eaten = i;
}
}
}
return 0;
}

// // BLANK FILLING #2 (Define everything in class "Cell" and its derived class)
// Step 3: initialize the static members
int Cell::resource = 500;
int NewCell::counter = 0;

// Step 4: define all methods in classes

/// @brief Constructor of the initial cell (Cell #0).
istream &operator>>(istream& input, Cell& initialCell) {
int spawnSize;
input >> spawnSize;
// User must input an integer within range [1, 100].
if (spawnSize < 1 || spawnSize > 100) {
cerr << "*** Invalid input! The input is now changed to 1. ***" << endl;
spawnSize = 1;
}
initialCell.size = spawnSize;
Cell::resource -= spawnSize;
cout << "Initial Cell is born, remaining resource = " << Cell::resource << endl;
return input;
}

/// @brief Let the initial cell eat.
ostream& operator<<(ostream& output, NewCell& target) {
NewCell::resource += target.size;
target.size -= target.size;
output << "Cell " << target.id << " is eaten, remaining resource = " << NewCell::resource << endl;
return output;
}

/// @brief Constructor of new normal cells.
bool NewCell::operator=(Cell& initialCell) {
if (this == &initialCell)
return true;
this -> id = counter++;
this -> size = initialCell.get_size() / 2;
resource -= initialCell.get_size() / 2;
cout << "Cell " << id << " is born, remaining resource = " << Cell::resource << endl;
return false;
}

/// @brief Spawn more normal cells if the resources are enough.
bool NewCell::operator=(NewCell& source) {
if (this == &source)
return true;
if (resource < source.size / 2)
return false;
this -> id = counter++;
this -> size = source.size / 2;
resource -= source.size / 2;
cout << "Cell " << id << " is born, remaining resource = " << Cell::resource << endl;
return false;
}

/// @brief Let the initial cell grow.
bool Cell::grow(void) {
if (resource <= 0)
return true;
resource--;
cout << "Initial Cell grows, remaining resource = " << resource << endl;
return false;
}

/// @brief Let normal cells grow.
bool NewCell::grow(void) {
if (resource <= 0)
return true;
this -> size++;
resource--;
cout << "Cell " << id << " grows, remaining resource = " << resource << endl;
return false;
}
// Write some code above.

Stage 12

The Requirements

Please fill all the blanks in the code below so that the program reads data of some characters from two files called actors_int.txt and actors_float.txt, and store into an array of Actor<int> and Actor<float> each. The total of characters of the two groups may not be equal but all characters from the two groups are no more than 20, to team up.

Then, according to threshold entered by the user, the program selects and outputs the qualified characters from the team to file team.txt. The qualified characters are required to meet at least three of the following four conditions: 1) HP is greater than threshold; 2) ATK is higher than threshold / 3; 3) DEF is higher than threshold / 3; 4) able to heal.

The output IDs are re-numbered from 1 in the order of int first and float then, and the internal characters of int (or float) are sorted from small to large according to the original IDs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <fstream>
#define NUM 20
using namespace std;

class Team;
template <class T> class Actor;
// Declare a function template below.
// Declare a function template above.

template <class T>
class Actor {
// Declare a friend which is a overload function template of the input operator of class "Actor".
// Declare a friend which is a overload function of the input operator of class "Team".
private:
int id;
char name[10];
T hp;
T atk;
T def;
public:
bool heal;
Actor(int i = 0, bool h = false): id(i), heal(h) {}
};

class Team {
// Declare a friend, three private data members and define a public constructor.
};

int main() {
// Declare two arrays below.
char waste[100], test;
int threshold, i;
// Declare two arrays above.
// Write some code below to read files. Do not define new objects unless file stream objects.
cout << "Standard (%): ";
cin >> threshold;
Team team(intActor, floatActor, threshold);
ofstream fout("team.txt");
fout << team;
fout.close();
return 0;
}

// Define the overload function template of the input operator of class "Actor".

// Define the overload function of the input operator of class "Team".

Additional Files

actors_int.txt

1
2
3
4
5
6
7
8
9
10
11
12
ID	Name	HP	ATK	DEF
1 Wilson 55 15 30
2 Carl 58 28 21 healer
3 Emma 65 25 28 healer
4 Warren 84 18 18
5 Larissa 79 16 13
6 Edith 54 13 24
7 Kevin 94 12 14
8 James 62 20 18
9 Sophia 82 22 14
10 Solomon 66 10 23

actors_float.txt

1
2
3
4
5
6
7
8
9
10
11
12
ID	Name	HP	ATK	DEF
1 Ashley 73.278 27.342 19.882
2 Leon 66.054 27.828 29.293 healer
3 Barry 62.963 26.368 11.124
4 Benson 61.781 16.626 28.525
5 May 84.577 24.367 21.595
6 Albert 98.882 27.505 29.476
7 Bruce 86.719 22.804 23.628
8 Joyce 63.356 23.636 18.379
9 Paul 79.968 27.674 16.616 healer
10 Ivy 86.747 29.786 28.03

team.txt while threshold is 60

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ID	Name	HP	ATK	DEF
1 Carl 58 28 21 healer
2 Emma 65 25 28 healer
3 Warren 84 18 18
7 James 62 20 18
5 Ashley 73.278 27.342 19.882
6 Leon 66.054 27.828 29.293 healer
7 Benson 61.781 16.626 28.525
8 May 84.577 24.367 21.595
9 Albert 98.882 27.505 29.476
10 Bruce 86.719 22.804 23.628
11 Joyce 63.356 23.636 18.379
12 Paul 79.968 27.674 16.616 healer
13 Ivy 86.747 29.786 28.03

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
///
/// @file 20-operator-overloads.cc
/// @author Lucis Urbe
/// @copyright Shanghai Jiao Tong University, 2019
/// @date January 12, 2024
/// @version 0.2
/// @brief The use of fstream objects.
/// @note Do not moidify or write more code unless allowed in
/// the limited places (see comments).
///

#include <iostream>
#include <fstream>
#define NUM 20
using namespace std;

class Team;
template <class T> class Actor;
// Declare a function template below.
template <class T> ifstream &operator>>(ifstream&, Actor<T>&);
// Declare a function template above.

template <class T>
class Actor {
// Declare a friend which is a overload function template of the input operator of class "Actor".
template <class Type>
friend ifstream &operator>>(ifstream&, Actor<Type>&);
//
// Declare a friend which is a overload function of the input operator of class "Team".
friend ofstream &operator<<(ofstream&, Team&);
//
private:
int id;
char name[10];
T hp;
T atk;
T def;
public:
bool heal;
Actor(int i = 0, bool h = false): id(i), heal(false) {} // heal(h)?
};

class Team {
// Declare a friend, three private data members and define a public constructor.
friend ofstream &operator<<(ofstream&, Team&);
private:
Actor<int> finalIntActor[NUM];
Actor<float> finalFloatActor[NUM];
int finalThreshold;
public:
Team(Actor<int>* intActor, Actor<float>* floatActor, int threshold) {
for (int i = 0; i < NUM; i++) {
finalIntActor[i] = intActor[i];
finalFloatActor[i] = floatActor[i];
}
finalThreshold = threshold;
}
//
};

int main() {
// Declare two arrays below.
Actor<int> intActor[NUM];
Actor<float> floatActor[NUM];
// Declare two arrays above.
char waste[100], test;
int threshold, i;
// Write some code below to read files. Do not define new objects unless file stream objects.
ifstream finInt("actors_int.txt"), finFloat("actors_float.txt");
if (!finInt) {
cout << "***Invalid input file \"actors_int.txt\". The program now exits.***" << endl;
return -1;
}
if (!finFloat) {
cout << "***Invalid input file \"actors_float.txt\". The program now exits.***" << endl;
return -2;
}
finInt >> waste >> waste >> waste >> waste >> waste;
for (i = 0; !finInt.eof() && i < NUM; i++) {
finInt >> intActor[i];
finInt.get(test);
if (test == '\t') {
intActor[i].heal = true;
finInt >> waste;
}
}
finFloat >> waste >> waste >> waste >> waste >> waste;
for (i = 0; !finFloat.eof() && i < NUM; i++) {
finFloat >> floatActor[i];
finFloat.get(test);
if (test == '\t') {
floatActor[i].heal = true;
finFloat >> waste;
}
}
//
cout << "Standard (%): ";
cin >> threshold;
Team team(intActor, floatActor, threshold);
ofstream fout("team.txt");
fout << team;
fout.close();
return 0;
}

// Define the overload function template of the input operator of class "Actor".
template <class T>
ifstream &operator>>(ifstream& input, Actor<T>& target) {
input >> target.id >> target.name >> target.hp >> target.atk >> target.def;
return input;
}
//

// Define the overload function of the input operator of class "Team".
ofstream &operator<<(ofstream& output, Team& target) {
output << "ID\tName\tHP\tATK\tDEF\n";
int i, j, flag;
for (i = j = flag = 0; i < NUM && target.finalIntActor[i].id == i + 1; i++) {
if (target.finalIntActor[i].hp > target.finalThreshold)
flag++;
if (target.finalIntActor[i].atk > target.finalThreshold / 3)
flag++;
if (target.finalIntActor[i].def > target.finalThreshold / 3)
flag++;
if (target.finalIntActor[i].heal)
flag++;
if (flag >= 3) {
j++;
output << i << '\t' << target.finalIntActor[i].name << '\t' << target.finalIntActor[i].hp << '\t' << target.finalIntActor[i].atk << '\t' << target.finalIntActor[i].def;
if (target.finalIntActor[i].heal)
output << "\thealer";
output << '\n';
}
flag = 0;
}
for (i = flag = 0; i < NUM && target.finalFloatActor[i].id == i + 1; i++) {
if (target.finalFloatActor[i].hp > target.finalThreshold)
flag++;
if (target.finalFloatActor[i].atk > target.finalThreshold / 3)
flag++;
if (target.finalFloatActor[i].def > target.finalThreshold / 3)
flag++;
if (target.finalFloatActor[i].heal)
flag++;
if (flag >= 3) {
output << ++j << '\t' << target.finalFloatActor[i].name << '\t' << target.finalFloatActor[i].hp << '\t' << target.finalFloatActor[i].atk << '\t' << target.finalFloatActor[i].def;
if (target.finalFloatActor[i].heal)
output << "\thealer";
output << '\n';
}
flag = 0;
}
return output;
}
//

Conclusion

The article overall reviews the basic skills the first learners needed in C++. It is definitely beneficial to the following learning of computer science if all the codes above are comprehended and can be skilledly rewritten.


Solving the Following Questions with C++
https://lucisurbe.pages.dev/2021/01/30/Solving-the-Following-Questions-with-C/
Author
Lucis Urbe
Posted on
January 30, 2021
Licensed under