Lab0_Welcome
Problem A: Rubik’s Cube
Description
On the original classic Rubik’s Cube, each of the six faces was covered by nine stickers. Each face has its own color, which is determined by the central sticker, since that the positions of all six central stickers will never be changed.
Now, given a face of Rubik’s Cube, try to find out the color of it.
Input
The first line of input is the number of test cases $T$ ($1\leq T \leq 100$)
For each test case, there are three lines, each line will only contain three upper case English letters, separated by a single blank, which shows the color of stickers.
Output
For each test case, print only one upper case English letter to show the color of the face.
Sample Input
1 | 2 |
2 | A B C |
3 | D E F |
4 | A B C |
5 | |
6 | Z Z Z |
7 | Z Z Z |
8 | Z Z Z |
Sample Output
1 | E |
2 | Z |
Code
1 | public class Main { |
2 | public static void main(String[] args) { |
3 | java.util.Scanner input = new java.util.Scanner(System.in); |
4 | |
5 | int n = input.nextInt(); |
6 | |
7 | for(int num = 0; num < n; num++) { |
8 | int t = 4; |
9 | while(t-->0) {input.next();} |
10 | System.out.println(input.next()); |
11 | t = 4; |
12 | while(t-->0) {input.next();} |
13 | } |
14 | input.close(); |
15 | } |
16 | } |
17 | /************************************************************** |
18 | Problem: 1198 |
19 | User: |
20 | Language: Java |
21 | Result: Accepted |
22 | Time:176 ms |
23 | Memory:17752 kb |
24 | ****************************************************************/ |
Problem B: Sudoku
Description
For a classic Sudoku, your aim is to fill a 99 grid with digits so that each column, each row, and each of the nine 33 sub grids that compose the grid contain all of the digits from 1 to 9. To make it easier, we guarantee that:
If you choose the order wisely, you can always find such a special blank that its row (column, or 33 sub grid) has already been filled with 8 numbers, so that you can determine its value quite easily. (*Hint may help you understand the definition of special blanks).
However, if you cannot find such special blank till you complete the Sudoku, just point out that the test data is incorrect.
Input
There is a Sudoku presented by ‘1~9’ and ‘ x ’. ‘x’ shows the blank you need to fill.(More details can be found at Sample input.) (Number of ‘x’s is greater than 1.)
Output
If you can always find ‘special blank’ till you complete the sudoku, print your solution of Sudoku as the given format. Otherwise print ‘The test data is incorrect!’(without quotes), instead.
Sample Input
1 | 6 1 8 | 5 3 7 | 4 9 2 | |
2 | 5 9 4 | 1 8 2 | 6 3 7 | |
3 | 2 3 7 | 4 6 9 | 8 5 1 | |
4 | |
5 | 3 7 2 | 6 5 1 | 9 x 8 | |
6 | 9 4 5 | 3 x 8 | 1 x 6 | |
7 | 1 8 6 | 2 9 4 | 5 7 3 | |
8 | |
9 | 7 6 3 | 8 4 5 | 2 1 9 | |
10 | 8 5 1 | 9 2 3 | 7 6 4 | |
11 | 4 2 9 | 7 1 6 | 3 8 5 | |
Sample Output
1 | 6 1 8 | 5 3 7 | 4 9 2 | |
2 | 5 9 4 | 1 8 2 | 6 3 7 | |
3 | 2 3 7 | 4 6 9 | 8 5 1 | |
4 | |
5 | 3 7 2 | 6 5 1 | 9 4 8 | |
6 | 9 4 5 | 3 7 8 | 1 2 6 | |
7 | 1 8 6 | 2 9 4 | 5 7 3 | |
8 | |
9 | 7 6 3 | 8 4 5 | 2 1 9 | |
10 | 8 5 1 | 9 2 3 | 7 6 4 | |
11 | 4 2 9 | 7 1 6 | 3 8 5 | |
HINT
‘Special blank’ means that its row has been filled with 8 numbers, or its column has been filled with 8 numbers, or its 3*3 sub grid has been filled with 8 numbers.
For the sample input, you can choose the order (5,5),(4,8),(5,8) to fill the blank. Initially, (5,5) and (4,8) are the ‘special blanks’, since that (5,5)’s 3*3 sub grid and (4,8)’s row have already been filled with eight numbers. When (5,5) is filled, (5,8) becomes a new ‘special blank’. After filling (4,8) and (5,8), the sudoku is completed.
6 1 8 | 5 3 7 | 4 9 2 |
5 9 4 | 1 X X | 6 3 7 |
2 3 7 | 4 6 9 | 8 5 1 |
3 7 2 | 6 5 1 | 9 4 8 |
9 4 5 | 3 X X | 1 2 6 |
1 8 6 | 2 9 4 | 5 7 3 |
7 6 3 | 8 4 5 | 2 1 9 |
8 5 1 | 9 2 3 | 7 6 4 |
4 2 9 | 7 1 6 | 3 8 X |
For this test case, the most lower-right x is the first ‘special blank’ that we seek. However, after filling that, you can not find any other ‘special blank’, so just print ‘The test data is incorrect!’
Code
1 | public class Main { |
2 | private static int[][] sudoku = new int[9][9]; |
3 | private static java.util.Stack<Integer[]> coordinates = new java.util.Stack<>(); |
4 | private static int[][] coo; |
5 | |
6 | public static void main(String[] args) { |
7 | java.util.Scanner input = new java.util.Scanner(System.in); |
8 | for(int i=0; i<sudoku.length; i++) { |
9 | for(int j=0; j<sudoku[i].length; j++) { |
10 | String s = input.next(); |
11 | if(s.equals("|")) {s = input.next();} |
12 | if(s.equals("x")) { |
13 | Integer[] coordinate = {i, j, position(i, j)}; |
14 | coordinates.push(coordinate); |
15 | continue; |
16 | } |
17 | sudoku[i][j] = Integer.parseInt(s); |
18 | } |
19 | } |
20 | input.close(); |
21 | |
22 | exchange(); |
23 | int n = coo.length; |
24 | |
25 | do { |
26 | boolean[][] ways = Judge(); |
27 | for(int i=0; i<coo.length; i++) { |
28 | if(ways[i][0] && ways[i][1] && ways[i][2]) { |
29 | Integer[] t = {coo[i][0], coo[i][1], coo[i][2]}; |
30 | coordinates.push(t); |
31 | } |
32 | else { |
33 | if(!ways[i][0]) way0(coo[i]); |
34 | else if(!ways[i][1]) way1(coo[i]); |
35 | else if(!ways[i][2]) way2(coo[i]); |
36 | } |
37 | } |
38 | exchange(); |
39 | if(n==coo.length) { |
40 | System.out.println("The test data is incorrect!"); |
41 | return; |
42 | } |
43 | else { |
44 | n = coo.length; |
45 | } |
46 | } while(coo.length != 0); |
47 | |
48 | printSudoku(); |
49 | } |
50 | |
51 | private static int position(int x, int y) { |
52 | int a = 0; |
53 | switch(x/3) { |
54 | case 2: a += 3; |
55 | case 1: a += 3; |
56 | case 0: |
57 | } |
58 | return a + y/3; |
59 | } |
60 | |
61 | private static void exchange() { |
62 | coo = new int[coordinates.size()][3]; |
63 | for(int i=coo.length-1; i>=0; i--) { |
64 | Integer[] temp = coordinates.pop(); |
65 | coo[i][0] = temp[0]; |
66 | coo[i][1] = temp[1]; |
67 | coo[i][2] = temp[2]; |
68 | } |
69 | } |
70 | |
71 | private static boolean[][] Judge() { |
72 | boolean[][] ways = new boolean[coo.length][3]; |
73 | for(int i=0; i<coo.length; i++) { |
74 | for (int j = i + 1; j < coo.length; j++) { |
75 | if (coo[i][0] == coo[j][0]) { |
76 | ways[i][0] = true; |
77 | ways[j][0] = true; |
78 | } |
79 | if (coo[i][1] == coo[j][1]) { |
80 | ways[i][1] = true; |
81 | ways[j][1] = true; |
82 | } |
83 | if (coo[i][2] == coo[j][2]) { |
84 | ways[i][2] = true; |
85 | ways[j][2] = true; |
86 | } |
87 | } |
88 | } |
89 | return ways; |
90 | } |
91 | |
92 | private static void way0(int[] coo) { |
93 | int sum = 0; |
94 | for(int i=0; i<sudoku.length; i++) { |
95 | sum += sudoku[coo[0]][i]; |
96 | } |
97 | sudoku[coo[0]][coo[1]] = 45 - sum; |
98 | } |
99 | |
100 | private static void way1(int[] coo) { |
101 | int sum = 0; |
102 | for(int i=0; i<sudoku.length; i++) { |
103 | sum += sudoku[i][coo[1]]; |
104 | } |
105 | sudoku[coo[0]][coo[1]] = 45 - sum; |
106 | } |
107 | |
108 | private static void way2(int[] coo) { |
109 | int[] startPoint = new int[2]; |
110 | switch(coo[2]) { |
111 | case 2: startPoint[1] += 3; |
112 | case 1: startPoint[1] += 3; |
113 | case 0: break; |
114 | case 5: startPoint[1] += 3; |
115 | case 4: startPoint[1] += 3; |
116 | case 3: { |
117 | startPoint[0] = 3; |
118 | break; |
119 | } |
120 | case 8: startPoint[1] += 3; |
121 | case 7: startPoint[1] += 3; |
122 | case 6: startPoint[0] = 6; |
123 | } |
124 | int sum = 0; |
125 | for(int i=startPoint[0]; i<startPoint[0]+3; i++) { |
126 | for(int j=startPoint[1]; j<startPoint[1]+3; j++) { |
127 | sum += sudoku[i][j]; |
128 | } |
129 | } |
130 | sudoku[coo[0]][coo[1]] = 45 - sum; |
131 | } |
132 | |
133 | private static void printSudoku() { |
134 | for(int i=0; i<sudoku.length; i++) { |
135 | for(int j=0; j<sudoku[i].length; j++) { |
136 | System.out.print(sudoku[i][j]+" "); |
137 | if(j%3 == 2) { |
138 | System.out.print('|'); |
139 | if(j==sudoku[i].length-1) System.out.println(); |
140 | else System.out.print(' '); |
141 | } |
142 | } |
143 | if(i%3 == 2) System.out.println(); |
144 | } |
145 | } |
146 | } |
147 | |
148 | /************************************************************** |
149 | Problem: 1202 |
150 | User: |
151 | Language: Java |
152 | Result: Accepted |
153 | Time:188 ms |
154 | Memory:18444 kb |
155 | ****************************************************************/ |
Problem C: Majsoul
Description
Mahjong, one of the most famous games in China, has aroused lanran’s interest. However, it is a little bit complex for a new bee and he needs your help: To sort 13 Mahjong tiles in order, so that he can make decision much easier. Here is the rule of sorting Mahjong tiles:
1.Mahjong tiles can be roughly divided into four types, ‘ 萬’ , ‘ 筒’, ’ 条’, ‘ 字’. For the first three types, each type has 9 different numbers(‘1’ to ‘9’), usually noted by ‘1萬’, ‘2萬’,’1条’,’2条’. If you still get puzzled, just imagine that we express the cards in ‘UNO’ by a number and a Chinese character rather than a colour. For the last type, there are only 7 kinds of tiles, ‘ 東’, ‘ 南’, ‘ 西’, ‘北’, ’白’, ’發’,’中’.
2.‘ 萬 ’ noted by ‘Wx’( x is an integer between ‘1’ to ‘9’), for example (W1,W2,…). Similarly, ‘ 筒 ’ by ‘Tx’, ‘ 条 ’ by ‘Yx’. We name those 7 tiles of the last type by ‘E’,’S’,’W’,’N’,’B’,’F’,’Z’ correspondingly.
3.Here is the priority of Mahjong tiles:
Wx>Tx>Yx>E>S>W>N>B>F>Z
For the same type:
W1>W2>W3>W4>W5>W6>W7>W8>W9
Notice that: For each kind of tile, there are totally four duplicate ones.
Input
The first line of input is the number of test cases $T$($1\leq T\leq 200$)
For each test case, there are 13 strings in one line, showing the Mahjong tiles you have.
Output
For each test case, output the ordered Mahjong tiles in one line.
Sample Input
1 | 2 |
2 | W1 S S N E N E N W E W W S |
3 | T1 T2 T3 T5 T8 T9 T6 T4 T7 T9 T9 T1 T1 |
Sample Output
1 | W1 E E E S S S W W W N N N |
2 | T1 T1 T1 T2 T3 T4 T5 T6 T7 T8 T9 T9 T9 |
Code
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | |
8 | enum Majhong { Z, F, B, N, W, S, E, Yx, Tx, Wx, Nil }; |
9 | |
10 | |
11 | Majhong determine(string mah) { |
12 | if (mah.size() == 1) { |
13 | if (mah.compare("Z") == 0) return Z; |
14 | if (mah.compare("F") == 0) return F; |
15 | if (mah.compare("B") == 0) return B; |
16 | if (mah.compare("N") == 0) return N; |
17 | if (mah.compare("W") == 0) return W; |
18 | if (mah.compare("S") == 0) return S; |
19 | if (mah.compare("E") == 0) return E; |
20 | } |
21 | else { |
22 | if (mah[0] == 'Y') return Yx; |
23 | if (mah[0] == 'T') return Tx; |
24 | if (mah[0] == 'W') return Wx; |
25 | } |
26 | return Nil; |
27 | } |
28 | |
29 | |
30 | bool compare(string a, string b) { |
31 | if (a.size() > b.size()) return true; |
32 | else if (a.size() > b.size()) return false; |
33 | else { |
34 | Majhong aM; |
35 | aM = determine(a); |
36 | Majhong bM; |
37 | bM = determine(b); |
38 | if (aM > bM) return true; |
39 | else if (aM < bM) return false; |
40 | else if (aM == bM && a.size() == 1) return true; |
41 | else { |
42 | if (a[1] <= b[1]) return true; |
43 | else if (a[1] > b[1]) return false; |
44 | } |
45 | } |
46 | return false; |
47 | } |
48 | |
49 | |
50 | int main() { |
51 | int times; |
52 | cin >> times; |
53 | |
54 | while (times-- > 0) { |
55 | string mahjong[13]; |
56 | for (int i = 0; i < 13; i++) { |
57 | cin >> mahjong[i]; |
58 | } |
59 | sort(mahjong, mahjong + 13, compare); |
60 | |
61 | for (int i = 0; i < 13; i++) { |
62 | cout << mahjong[i]; |
63 | cout << " "; |
64 | } |
65 | cout << endl; |
66 | } |
67 | return 0; |
68 | } |
69 | |
70 | /************************************************************** |
71 | Problem: 1247 |
72 | User: |
73 | Language: C++ |
74 | Result: Accepted |
75 | Time:8 ms |
76 | Memory:1720 kb |
77 | ****************************************************************/ |
Problem D: Magical Number
Description
We want to find those Magical Numbers which are symmetry, that is, no matter whether you count it from left to right or right to left, its value will not be changed. For example, 1, 121, 12321, are Magic Numbers, but 123, 321, are not. To be more precise, suppose that we present a number by array a of size n (index starts with 1). It is a Magical Number if and only if $a[i]=a[n-i+1]$ for any$i$, $1\leq i\leq n$. Notice that Magical Number are non-negative integers.
You are asked to count how many Magical Numers are smaller or equal than an integer N.
Input
The first line of input is the number of test cases $T$ ($1\leq T\leq 20$)
For each test case, there is only one integer $N$($0\leq N\leq 1011$)
Notice that: the maximum value of a signed 32-bit integer is 2147483647
‘long long’ in C++, ‘long’ in Java is recommended.
Output
One line for each test case, print the result you get.
Sample Input
1 | 2 |
2 | 1 |
3 | 11 |
Sample Output
1 | 2 |
2 | 11 |
HINT
Try to construct all the required Magical Numbers rather than check it from 1 to N.
Code
1 |
|
2 |
|
3 | |
4 | |
5 | using namespace std; |
6 | |
7 | |
8 | |
9 | long long len(long long num) { |
10 | long long n = 0; |
11 | while (num != 0) { |
12 | num /= 10; |
13 | n++; |
14 | } |
15 | return n; |
16 | } |
17 | |
18 | |
19 | long long zonetotal(long long len) { |
20 | if (len == 0) return 0; |
21 | if (len == 1) return 10; |
22 | return 9 * (long long)pow(10, (len - 1) / 2); |
23 | } |
24 | |
25 | |
26 | long long func(long long len) { |
27 | if (len == 0) return 0; |
28 | if (len == 1) return 10; |
29 | return func(len - 1) + zonetotal(len); |
30 | } |
31 | |
32 | |
33 | long long piecenumber(long long* piece, long long startp, long long endp) { |
34 | if (startp == 0) { |
35 | if (endp == startp) return piece[startp] - 1; |
36 | else return (piece[startp] - 1) * pow(10, (endp - startp)) + piecenumber(piece, startp + 1, endp); |
37 | } |
38 | if (endp == startp) return piece[startp]; |
39 | return piece[startp] * pow(10, (endp - startp)) + piecenumber(piece, startp + 1, endp); |
40 | } |
41 | |
42 | |
43 | bool isplus(long long* left, long long* right, long long half) { |
44 | for (long long i = half - 1; i >= 0; i--) { |
45 | int a = left[i]; |
46 | int b = right[i]; |
47 | if (left[i] == right[i]) continue; |
48 | if (left[i] < right[i]) return true; |
49 | return false; |
50 | } |
51 | return true; |
52 | } |
53 | |
54 | |
55 | long long zonepart(long long num) { |
56 | long long length = len(num); |
57 | if (length == 1) return num + 1; |
58 | long long half = (length + 1) / 2; |
59 | long long left[23] = { 0 }; |
60 | long long right[23] = { 0 }; |
61 | for (long long i = 0; i < half; i++) { |
62 | right[i] = num % 10; |
63 | num /= 10; |
64 | } |
65 | if (length & 1) { |
66 | for (long long i = 0; i < half - 1; i++) { |
67 | left[half - i - 2] = num % 10; |
68 | num /= 10; |
69 | } |
70 | left[half - 1] = right[half - 1]; |
71 | } |
72 | else { |
73 | for (long long i = 0; i < half; i++) { |
74 | left[half - i - 1] = num % 10; |
75 | num /= 10; |
76 | } |
77 | } |
78 | |
79 | int p = piecenumber(left, 0, half - 1); |
80 | bool isss = isplus(left, right, half); |
81 | return piecenumber(left, 0, half - 1) + (isplus(left, right, half) ? 1 : 0); |
82 | } |
83 | |
84 | |
85 | int main() { |
86 | long long times; |
87 | cin >> times; |
88 | while (times-- > 0) { |
89 | long long num; |
90 | cin >> num; |
91 | if (num / 10 == 0) { |
92 | cout << num + 1 << endl; |
93 | continue; |
94 | } |
95 | int ttt = func(len(num) - 1); |
96 | long long total = zonepart(num) + func(len(num) - 1); |
97 | cout << total << endl; |
98 | } |
99 | return 0; |
100 | } |
101 | |
102 | /************************************************************** |
103 | Problem: 1248 |
104 | User: |
105 | Language: C++ |
106 | Result: Accepted |
107 | Time:0 ms |
108 | Memory:1908 kb |
109 | ****************************************************************/ |
Problem E: Down, Right and Up!
Description
How to count an infinity set? For example, all the points in a 2-D space which have positive integer coordinates. lanran finds a way to solve that, ‘Down, Right and Up!’ Let’s see how we count first several points by the above way.
How do we count more?
Hopefully, you have understood this procedure well. Similarly, we can expand the ‘matrix’ to infinitely large, that is, we can count all the points which have positive integer coordinates in a 2-D space.
Given a coordinate, you need to return its index and given an index, you need to return its coordinate.
Input
The first line of input is the number of test cases $T$ ($1\leq T \leq 100,000$)
For each test case, there could only be a coordinate,$(x,y)$ or an index a.($1\leq x,y\leq 109$ , $1\leq a\leq 1018$) You may need ‘long long’ in C++, or ‘long’ in Java to store the value of a.
Output
The coordinate or index that matches each query.
Sample Input
1 | 2 |
2 | 1 |
3 | (1,2) |
Sample Output
1 | (1,1) |
2 | 4 |
Code
1 |
|
2 |
|
3 |
|
4 |
|
5 | |
6 | |
7 | using namespace std; |
8 | |
9 | |
10 | long long point[2] = { 1, 1 }; |
11 | long long p[2] = { 0, 0 }; |
12 | long long number; |
13 | stringstream ss; |
14 | |
15 | |
16 | long long num2point(long long num) { |
17 | if (num <= 4) { |
18 | switch (num) { |
19 | case 2: point[0] += 1; |
20 | case 1: |
21 | default: return 0; |
22 | case 3: point[0] += 1; |
23 | case 0: |
24 | case 4: point[1] += 1; |
25 | } |
26 | return 0; |
27 | } |
28 | |
29 | long long piece = floor(logbl(num - 1) / 2); |
30 | long long blocksize = powl(4, piece); |
31 | long long blocknum = num / blocksize; |
32 | long long blocklen = sqrtl(blocksize); |
33 | long long least = num - blocksize * blocknum; |
34 | if (num % blocksize == 0) least = blocksize; |
35 | |
36 | switch ((num - 1) / blocksize) { |
37 | case 1: { |
38 | point[0] += blocklen; |
39 | break; |
40 | } |
41 | case 2: point[0] += blocklen; |
42 | case 3: point[1] += blocklen; |
43 | } |
44 | |
45 | return num2point(least); |
46 | } |
47 | |
48 | |
49 | void findpoint(long long num) { |
50 | point[0] = point[1] = 1; |
51 | num2point(num); |
52 | } |
53 | |
54 | |
55 | long long* point2num(long long* p) { |
56 | long long maxp = fmaxl(p[0], p[1]); |
57 | if (maxp <= 2) { |
58 | switch (p[0]) { |
59 | case 1: { |
60 | switch (p[1]) { |
61 | case 2: number += 3; |
62 | case 1: number += 1; |
63 | default: { |
64 | p[0] = p[1] = 0; |
65 | return p; |
66 | } |
67 | } |
68 | } |
69 | case 2: { |
70 | switch (p[1]) { |
71 | case 2: number += 1; |
72 | case 1: number += 2; |
73 | default: { |
74 | p[0] = p[1] = 0; |
75 | return p; |
76 | } |
77 | } |
78 | } |
79 | } |
80 | } |
81 | long long piece = floor(logbl(maxp-1)); |
82 | long long blocksize = powl(4, piece); |
83 | long long blocklen = sqrtl(blocksize); |
84 | bool isaxisX = p[0] > blocklen; |
85 | bool isaxisY = p[1] > blocklen; |
86 | switch (isaxisX && isaxisY) { |
87 | case true: { |
88 | number += blocksize * 2; |
89 | p[0] -= blocklen; |
90 | p[1] -= blocklen; |
91 | return point2num(p); |
92 | } |
93 | case false: { |
94 | if (isaxisX) { |
95 | number += blocksize; |
96 | p[0] -= blocklen; |
97 | return point2num(p); |
98 | } |
99 | else { |
100 | number += blocksize * 3; |
101 | p[1] -= blocklen; |
102 | return point2num(p); |
103 | } |
104 | } |
105 | } |
106 | } |
107 | |
108 | |
109 | void findnum(long long* p) { |
110 | number = 0; |
111 | point2num(p); |
112 | } |
113 | |
114 | long long* str2point(string str) { |
115 | p[0] = 0; |
116 | p[1] = 0; |
117 | auto comma = str.find(","); |
118 | if (comma == string::npos) return p; |
119 | auto len = str.length(); |
120 | auto p0 = str.substr(1, comma - 1); |
121 | auto p1 = str.substr(comma + 1, len - comma - 2); |
122 | ss.clear(); |
123 | ss << p0; |
124 | ss >> p[0]; |
125 | ss.clear(); |
126 | ss << p1; |
127 | ss >> p[1]; |
128 | return p; |
129 | } |
130 | |
131 | long long str2ll(string str) { |
132 | long long ll; |
133 | ss.clear(); |
134 | ss << str; |
135 | ss >> ll; |
136 | return ll; |
137 | } |
138 | |
139 | int main() { |
140 | long long times; |
141 | cin >> times; |
142 | while (times-- > 0) { |
143 | string str; |
144 | cin >> str; |
145 | long long* p = str2point(str); |
146 | if (p[0] == 0) { |
147 | long long num = str2ll(str); |
148 | findpoint(num); |
149 | cout << "(" << point[0] << "," << point[1] << ")" << endl; |
150 | continue; |
151 | } |
152 | findnum(p); |
153 | cout << number << endl; |
154 | } |
155 | } |
156 | /************************************************************** |
157 | Problem: 1249 |
158 | User: |
159 | Language: C++ |
160 | Result: Accepted |
161 | Time:1244 ms |
162 | Memory:4844 kb |
163 | ****************************************************************/ |
Problem F: Summer camp
Description
This summer holiday, members in SUSTechCPC went to Qinhuangdao to participate in a summer camp there. As they enjoyed a lot, they decided to take a group photo.
There are n member(s) in SUSTechCPC, and they want to stand in $k(k≥2)$ rows because it is too crowded to stand in only one row. To make the photo more beautiful, the number of people standing in the $i^{th}$ row should be exactly one more than the number of people standing in the $(i−1)^{th}$ row. Since they do not want to stand in too many rows, please tell them the minimum possible number of rows kk or determine that it is impossible to find any valid arrangement.
Input
The first line of the input contains one integer $T$, indicates the number of testcases.
For each testcase, there is only one line contains one integer $n$($1≤n≤1 000 000 000$).
Output
Print one single integer, the minimum possible $k$ described above.
If there is no such $k$, please output ‘impossible’ (without quotes).
Sample Input
1 | 3 |
2 | 8 |
3 | 10 |
4 | 24 |
Sample Output
1 | impossible |
2 | 4 |
3 | 3 |
HINT
10 = 1 + 2 + 3 + 4
24 = 7 + 8 + 9
1 |
|
2 |
|
3 | |
4 | |
5 | using namespace std; |
6 | |
7 | |
8 | |
9 | long double calX(long long n, long long members) { |
10 | return (members - (n * n - n) / 2l) / (long double)n; |
11 | } |
12 | |
13 | |
14 | bool islongeger(long double num) { |
15 | return abs(num - llround(num)) < 0.000000000000001; |
16 | } |
17 | |
18 | |
19 | long long calRow(long long members) { |
20 | long double uplim = (sqrtl(1 + 8 * members) - 1) / 2; |
21 | for (long i = 2; i <= uplim; i++) { |
22 | long double x = calX(i, members); |
23 | if (islongeger(x)) return i; |
24 | } |
25 | return -1; |
26 | } |
27 | |
28 | |
29 | int main() { |
30 | long long times; |
31 | cin >> times; |
32 | while (times-- > 0) { |
33 | long long members; |
34 | cin >> members; |
35 | long row = calRow(members); |
36 | if (row == -1) { |
37 | cout << "impossible" << endl; |
38 | continue; |
39 | } |
40 | cout << row << endl; |
41 | } |
42 | return 0; |
43 | } |
44 | /************************************************************** |
45 | Problem: 1246 |
46 | User: |
47 | Language: C++ |
48 | Result: Accepted |
49 | Time:0 ms |
50 | Memory:1740 kb |
51 | ****************************************************************/ |
Lab1_Algorithm
Problem A: [Easy I] Crazy Plan
Description
Neko is crazy at solving the algorithm problems recently. He sets a plan for himself:
The $1^{st}$ day, he will get on 1 problem solved.
The $2^{nd}$ day, he will get on 3 problems solved.
The $3^{rd}$ day, he will get on 6 problems solved.
…
The $nth$ day, he will get on $n(n+1)/2$ problems solved.
Neko wants to know how many problems he will solve after $K$ days.
Input
The first line contains a single integer $T$($1≤T≤1.1∗106$) —— the number of test case.
The 2nd2nd line to the $(T+1)th$ line, each line contains a single integer $K$($1≤K≤106$)—— the number of days.
Output
Print the number of problems Neko solved. Each test case for one line.
Sample Input
1 | 3 |
2 | 1 |
3 | 2 |
4 | 3 |
Sample Output
1 | 1 |
2 | 4 |
3 | 10 |
Code
1 |
|
2 | |
3 | using namespace std; |
4 | |
5 | |
6 | int main() { |
7 | long long times; |
8 | scanf("%lld", ×); |
9 | while (times-- > 0) { |
10 | long long n; |
11 | scanf("%lld", &n); |
12 | printf("%lld\n", n * (n + 1) * (n + 2) / 6); |
13 | } |
14 | return 0; |
15 | } |
16 | |
17 | /************************************************************** |
18 | Problem: 1250 |
19 | User: |
20 | Language: C++ |
21 | Result: Accepted |
22 | Time:172 ms |
23 | Memory:1092 kb |
24 | ****************************************************************/ |
1 | public class Main { |
2 | public static void main(String[] args) { |
3 | java.util.Scanner input = new java.util.Scanner(System.in); |
4 | long times = input.nextLong(); |
5 | while(times-->0) { |
6 | long n = input.nextLong(); |
7 | System.out.println(n*(n+1)*(n+2)/6); |
8 | } |
9 | input.close(); |
10 | } |
11 | } |
12 | |
13 | /************************************************************** |
14 | Problem: 1250 |
15 | User: |
16 | Language: Java |
17 | Result: Accepted |
18 | Time:3232 ms |
19 | Memory:41656 kb |
20 | ****************************************************************/ |
Problem B: [Easy II] Nearest Price
Description
Neko likes to eat fish recently. There are various kinds of fish in the market and Neko has XX dollars. If the market happens to have a fish with a price of XX, Neko will say “Meow“. Otherwise, Neko will buy the most expensive fish which he can afford and say the change. (If Neko can’t afford any fish, he will come back directly and say the money he has.)
Neko will go to the market with XX dollars for TT days. XX may change everyday but the kinds of fish in the market will never change.
Input
The first line contains a single integer $T$($1≤T≤106$) —— the number of the days when Neko needs to buy fish.
The second line contains a single integer $N$($1≤N≤106$) —— denoting there are/is NN kind(s) of fish in the market.
The third line contains TT integers$ x_1,x_2,x_3,…,x_T($1≤xi≤109$,$1≤i≤T$) —— the money Neko has for each day.
The fourth line contains NN integers $p_1,p_2,p_3,…,p_N$($1≤pi≤109,1≤i≤N$) which are the prices of the fish in the market.
It is guaranteed that prices are in ascending order.
Output
For each day, print only one line for what Neko said.
Sample Input
1 | 2 |
2 | 2 |
3 | 1 3 |
4 | 2 3 |
Sample Output
1 | 1 |
2 | Meow |
Code
1 |
|
2 | |
3 | using namespace std; |
4 | |
5 | int read_int(); |
6 | int* binarysearch(int* info); |
7 | |
8 | int info[4] = { 0 }; |
9 | int* prices; |
10 | |
11 | |
12 | int main() { |
13 | int days = read_int(); |
14 | int kinds = read_int(); |
15 | int* money = new int[days]; |
16 | prices = new int[kinds]; |
17 | for (int i = 0; i < days; i++) money[i] = read_int(); |
18 | for (int i = 0; i < kinds; i++) prices[i] = read_int(); |
19 | |
20 | for (int i = 0; i < days; i++) { |
21 | info[0] = 0; |
22 | info[1] = kinds - 1; |
23 | info[2] = money[i]; |
24 | binarysearch(info); |
25 | if (info[3] == -1) { |
26 | if (prices[info[0]] > info[2]) printf("%d\n", info[2]); |
27 | else if (prices[info[0]] < info[2] && info[2] < prices[info[1]]) printf("%d\n", info[2] - prices[info[0]]); |
28 | else printf("%d\n", info[2] - prices[info[1]]); |
29 | } |
30 | else printf("Meow\n"); |
31 | } |
32 | return 0; |
33 | } |
34 | |
35 | |
36 | int read_int() { |
37 | char r; |
38 | bool start = false, neg = false; |
39 | int ret = 0; |
40 | while (true) { |
41 | r = getchar(); |
42 | if ((r - '0' < 0 || r - '0'>9) && r != '-' && !start) { |
43 | continue; |
44 | } |
45 | if ((r - '0' < 0 || r - '0'>9) && r != '-' && start) { |
46 | break; |
47 | } |
48 | if (start)ret *= 10; |
49 | start = true; |
50 | if (r == '-')neg = true; |
51 | else ret += r - '0'; |
52 | } |
53 | if (!neg) |
54 | return ret; |
55 | else |
56 | return -ret; |
57 | } |
58 | |
59 | |
60 | int* binarysearch(int* info) { |
61 | if (info[1] - info[0] == 1) { |
62 | if (prices[info[0]] == info[2]) { |
63 | info[3] = info[0]; |
64 | return info; |
65 | } |
66 | else if (prices[info[1]] == info[2]) { |
67 | info[3] = info[1]; |
68 | return info; |
69 | } |
70 | else { |
71 | info[3] = -1; |
72 | return info; |
73 | } |
74 | } |
75 | auto mid = (info[0] + info[1]) / 2; |
76 | if (prices[mid] < info[2]) info[0] = mid; |
77 | else info[1] = mid; |
78 | return binarysearch(info); |
79 | } |
80 | |
81 | /************************************************************** |
82 | Problem: 1251 |
83 | User: |
84 | Language: C++ |
85 | Result: Accepted |
86 | Time:216 ms |
87 | Memory:9032 kb |
88 | ****************************************************************/ |
Problem C: [Median I] Factorial Magic
Description
Neko is a freshman at SUSTech and he is good at fractorial problems. He wants to challenge you to see if you can solve the following problem: Caculate the value of $((n!)!)!(mod m)$.
Input
There is only one line contains two integers $n,m$($0≤n≤109,1≤m≤109$).
Output
Print the value of $((n!)!)!(mod m)$.
Sample Input
1 | 1 2019 |
Sample Output
1 | 1 |
HINT
In mathematics, the factorial of a positive integer n, denoted by n!, is the product of all positive integers less than or equal to n: For example, The value of 0! is 1, according to the convention for an empty product.
Code
1 | import java.util.Scanner; |
2 | import java.math.BigInteger; |
3 | |
4 | public class Main { |
5 | public static void main(String[] args) { |
6 | Scanner input = new Scanner(System.in); |
7 | int n = input.nextInt(); |
8 | int m = input.nextInt(); |
9 | input.close(); |
10 | BigInteger result = new BigInteger("0"); |
11 | switch(n) { |
12 | case 0: |
13 | case 1: { |
14 | if(m != 1) result = new BigInteger("1"); |
15 | break; |
16 | } |
17 | case 2: { |
18 | if(m > 2) result = new BigInteger("2"); |
19 | break; |
20 | } |
21 | case 3: if (m > 720) result = new BigInteger("2601218943565795100204903227081043611191521875016945785727541837850835631156947382240678577958130457082619920575892247259536641565162052015873791984587740832529105244690388811884123764341191951045505346658616243271940197113909845536727278537099345629855586719369774070003700430783758997420676784016967207846280629229032107161669867260548988445514257193985499448939594496064045132362140265986193073249369770477606067680670176491669403034819961881455625195592566918830825514942947596537274845624628824234526597789737740896466553992435928786212515967483220976029505696699927284670563747137533019248313587076125412683415860129447566011455420749589952563543068288634631084965650682771552996256790845235702552186222358130016700834523443236821935793184701956510729781804354173890560727428048583995919729021726612291298420516067579036232337699453964191475175567557695392233803056825308599977441675784352815913461340394604901269542028838347101363733824484506660093348484440711931292537694657354337375724772230181534032647177531984537341478674327048457983786618703257405938924215709695994630557521063203263493209220738320923356309923267504401701760572026010829288042335606643089888710297380797578013056049576342838683057190662205291174822510536697756603029574043387983471518552602805333866357139101046336419769097397432285994219837046979109956303389604675889865795711176566670039156748153115943980043625399399731203066490601325311304719028898491856203766669164468791125249193754425845895000311561682974304641142538074897281723375955380661719801404677935614793635266265683339509760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").mod(new BigInteger(m+"")); |
22 | } |
23 | System.out.println(result); |
24 | } |
25 | } |
26 | |
27 | /************************************************************** |
28 | Problem: 1252 |
29 | User: |
30 | Language: Java |
31 | Result: Accepted |
32 | Time:220 ms |
33 | Memory:19184 kb |
34 | ****************************************************************/ |
Problem D: [Median II] Two-Product
Description
Neko thinks the two-sum problem is easy for you, so he tests you by a new problem —— the two-product problem.
Given an array of integers, $a_1,a_2,a_3,…,a_N$, and an integer $M$. Please output the number of pairs$ (a_i,a_j)$,$i<j$, such that $a_i∗a_j=M$.
Input
The first line contains a single integer $N$($1≤N≤106$) —— the length of the array.
The second line contains a single integer $M$($−1018≤M≤1018$) —— the specific target.
The third line contains NN integers $a_1,a_2,a_3,…,a_N$($−109≤a_i≤109,1≤i≤N$) —— an array of integers.
It is guaranteed that the array is sorted in ascending order.
Output
For each specific target, print only one line for the number of a numbers pairs $(a_i,a_j)$ satisfying $a_i∗a_j=M$.
Sample Input
1 | 9 |
2 | 4 |
3 | -4 -4 -2 -1 0 1 2 2 4 |
Sample Output
1 | 3 |
HINT
Duplicate pairs $(a_i,a_j)$ count only once!
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | int* array; |
7 | int info[4] = { 0 }; |
8 | |
9 | int binarysearch(); |
10 | |
11 | |
12 | int main() { |
13 | int arrlen; |
14 | scanf("%d", &arrlen); |
15 | long long int target; |
16 | scanf("%lld", &target); |
17 | array = new int[arrlen]; |
18 | bool* isSameBefore = new bool[arrlen]; |
19 | isSameBefore[0] = false; |
20 | for (int i = 0; i < arrlen; i++) { |
21 | scanf("%d", &(array[i])); |
22 | if (i != 0 && array[i] != array[i - 1]) { |
23 | isSameBefore[i] = false; |
24 | } |
25 | else if (i != 0) { |
26 | isSameBefore[i] = true; |
27 | } |
28 | } |
29 | |
30 | int times = 0; |
31 | if (target == 0) { |
32 | info[0] = 0; |
33 | info[1] = arrlen - 1; |
34 | info[2] = 0; |
35 | info[3] = -2; |
36 | binarysearch(); |
37 | if (info[3] != -1) { |
38 | for (int i = 0; i < arrlen; i++) { |
39 | if (!isSameBefore[i] && array[i] != 0) { |
40 | times++; |
41 | } |
42 | else if (array[i] == 0) { |
43 | if (i == arrlen - 1) { |
44 | break; |
45 | } |
46 | if (array[i + 1] == 0) { |
47 | times++; |
48 | for (int j = i + 1; j < arrlen; j++) { |
49 | if (!isSameBefore[j]) { |
50 | i = j - 1; |
51 | break; |
52 | } |
53 | else if (j == arrlen - 1) { |
54 | i = j; |
55 | break; |
56 | } |
57 | } |
58 | } |
59 | } |
60 | } |
61 | } |
62 | } |
63 | else { |
64 | for (int i = 0; i < arrlen - 1; i++) { |
65 | if (isSameBefore[i] || array[i] == 0) continue; |
66 | if (target % array[i] == 0) { |
67 | info[2] = target / array[i]; |
68 | if (info[2] < array[i]) continue; |
69 | info[0] = (long long int)i + 1; |
70 | info[1] = arrlen - 1; |
71 | info[3] = -2; |
72 | binarysearch(); |
73 | if (info[3] != -1) times++; |
74 | } |
75 | } |
76 | } |
77 | printf("%i\n", times); |
78 | return 0; |
79 | } |
80 | |
81 | |
82 | int binarysearch() { |
83 | if (info[1] - info[0] <= 1) { |
84 | if (array[info[0]] == info[2]) { |
85 | info[3] = info[0]; |
86 | return 0; |
87 | } |
88 | else if (array[info[1]] == info[2]) { |
89 | info[3] = info[1]; |
90 | return 0; |
91 | } |
92 | else { |
93 | info[3] = -1; |
94 | return -1; |
95 | } |
96 | } |
97 | auto mid = (info[0] + info[1]) / 2; |
98 | if (array[mid] < info[2]) info[0] = mid; |
99 | else info[1] = mid; |
100 | return binarysearch(); |
101 | } |
102 | |
103 | /************************************************************** |
104 | Problem: 1253 |
105 | User: |
106 | Language: C++ |
107 | Result: Accepted |
108 | Time:80 ms |
109 | Memory:6104 kb |
110 | ****************************************************************/ |
1 | import java.util.Arrays; |
2 | import java.util.Scanner; |
3 | |
4 | public class Main { |
5 | public static void main(String[] args) { |
6 | Scanner input = new Scanner(System.in); |
7 | int arrayLength = input.nextInt(); |
8 | long target = input.nextLong(); |
9 | long[] array = new long[arrayLength]; |
10 | boolean[] isSameBefore = new boolean[arrayLength]; |
11 | for(int i = 0; i<arrayLength; i++) { |
12 | array[i] = input.nextLong(); |
13 | if(i != 0 && array[i] == array[i - 1]) { |
14 | isSameBefore[i] = true; |
15 | } |
16 | } |
17 | input.close(); |
18 | |
19 | long times = 0; |
20 | if(target==0) { |
21 | if(Arrays.binarySearch(array, 0, arrayLength, 0) >= 0) { |
22 | for(int i = 0; i < arrayLength; i++) { |
23 | if(!isSameBefore[i] && array[i] != 0) { |
24 | times++; |
25 | } |
26 | else if(array[i] == 0) { |
27 | if(i == arrayLength - 1) { |
28 | break; |
29 | } |
30 | if(array[i + 1] == 0) { |
31 | times++; |
32 | for(int j = i + 1; j < arrayLength; j++) { |
33 | if(!isSameBefore[j]) { |
34 | i = j - 1; |
35 | break; |
36 | } |
37 | else if(j == arrayLength - 1) { |
38 | i = j; |
39 | break; |
40 | } |
41 | } |
42 | } |
43 | } |
44 | } |
45 | } |
46 | } |
47 | else { |
48 | for(int i = 0; i < arrayLength - 1; i++) { |
49 | if(isSameBefore[i] || array[i] == 0) continue; |
50 | if(target % array[i] == 0) { |
51 | long key = target/array[i]; |
52 | if(key<array[i]) continue; |
53 | if(Arrays.binarySearch(array, i+1, arrayLength, key) >= 0) { |
54 | times++; |
55 | } |
56 | } |
57 | } |
58 | } |
59 | System.out.println(times); |
60 | } |
61 | } |
62 | |
63 | /************************************************************** |
64 | Problem: 1253 |
65 | User: |
66 | Language: Java |
67 | Result: Accepted |
68 | Time:1092 ms |
69 | Memory:42520 kb |
70 | ****************************************************************/ |
Problem E: [Hard] Catch Neko
Description
Neko is running away! Eve wants to catch him. At first, Eve is standing at the point with coordinates $(x1,y1)$, while Neko is standing at the point with coordinates $(x2,y2)$. For every minute, Eve can choose to go up, down, left, or right with 1 unit distance. For instance, if she is at $(x,y)$ now, she can go to $(x,y+1),(x,y−1),(x−1,y)$ or $(x+1,y)$.
Eve noticed that Neko also moves 1 unit distance every minute, but he only moves according to a sequence periodically. The sequence only contains ‘U’,’D’,’L’,’R’, denoting that Neko moves up, down, left, right respectively.
Eve is now wondering how many minutes she needs at least to catch Neko.
Input
The first line contains two integers $x_1,y_1$($0≤x_1,y_1≤109$) —— the initial coordinate of Eve.
The second line contains two integers $x_2,y_2$($0≤x_2,y_2≤109$) —— the initial coordinate of Neko.
It is guaranteed that the initial coordinates and destination point coordinates are different.
The third line contains a single integer $N$($1≤N≤105$) —— the length of the sequence $S$.
The fourth line contains the string $S$ itself, consisting only four letters $U,D,L,R$.
Output
Please output the minimum minutes Eve needs to catch Neko. If she can not catch Neko forever, please output -1.
Sample Input
1 | 0 0 |
2 | 4 6 |
3 | 3 |
4 | DDD |
Sample Output
1 | 5 |
HINT
Eve can choose not to move at every minute.
Code
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | long long int seq[100000][2]; |
8 | |
9 | void move(long long int* p0, long long int* p1, char direction); |
10 | long long int calDistance(long long int p00, long long int p01, int* p1); |
11 | bool canCatch(long long int seq[][2], int seqlen, long long int* moveDistance, int* evePoint, long long int time); |
12 | long long int binarySearch(long long int seq[][2], int seqlen, long long int* moveDistance, int* evePoint, long long int low, long long int high); |
13 | |
14 | int main() { |
15 | int evePoint[2]; |
16 | scanf("%i %i", &evePoint[0], &evePoint[1]); |
17 | int nekoPoint[2]; |
18 | scanf("%i %i", &nekoPoint[0], &nekoPoint[1]); |
19 | int seqLength; |
20 | scanf("%i", &seqLength); |
21 | char* sequence = new char[seqLength]; |
22 | scanf("%s", sequence); |
23 | if (nekoPoint[0] == evePoint[0] && nekoPoint[1] == evePoint[1]) { |
24 | printf("%i\n", 0); |
25 | return 0; |
26 | } |
27 | move(new long long int[2]{ nekoPoint[0], nekoPoint[1] }, seq[0], sequence[0]); |
28 | for (int i = 1; i < seqLength; i++) { |
29 | move(seq[i - 1], seq[i], sequence[i]); |
30 | } |
31 | |
32 | long long int moveDistance[] = { seq[seqLength - 1][0] - nekoPoint[0], seq[seqLength - 1][1] - nekoPoint[1] }; |
33 | |
34 | if (!canCatch(seq, seqLength,moveDistance, evePoint, 1000000000000000000L)) { |
35 | printf("%i\n", -1); |
36 | return 0; |
37 | } |
38 | |
39 | long long int time = binarySearch(seq, seqLength, moveDistance, evePoint, 0, 1000000000000000000L) + 1; |
40 | printf("%lli\n", time); |
41 | return 0; |
42 | } |
43 | |
44 | void move(long long int* p0, long long int* p1, char direction) { |
45 | switch (direction) { |
46 | case 'R': { |
47 | p1[0] = p0[0] + 1; |
48 | p1[1] = p0[1]; |
49 | break; |
50 | } |
51 | case 'L': { |
52 | p1[0] = p0[0] - 1; |
53 | p1[1] = p0[1]; |
54 | break; |
55 | } |
56 | case 'U': { |
57 | p1[0] = p0[0]; |
58 | p1[1] = p0[1] + 1; |
59 | break; |
60 | } |
61 | case 'D': { |
62 | p1[0] = p0[0]; |
63 | p1[1] = p0[1] - 1; |
64 | break; |
65 | } |
66 | } |
67 | } |
68 | |
69 | long long int calDistance(long long int p00, long long int p01, int* p1) { |
70 | return abs(p00 - p1[0]) + abs(p01 - p1[1]); |
71 | } |
72 | |
73 | bool canCatch(long long int seq[][2], int seqlen, long long int* moveDistance, int* evePoint, long long int time) { |
74 | return time + 1 >= calDistance( |
75 | seq[(int)(time % seqlen)][0] + time / seqlen * moveDistance[0], |
76 | seq[(int)(time % seqlen)][1] + time / seqlen * moveDistance[1], |
77 | evePoint |
78 | ); |
79 | } |
80 | |
81 | long long int binarySearch(long long int seq[][2], int seqlen, long long int* moveDistance, int* evePoint, long long int low, long long int high) { |
82 | if (high - low <= 1) { |
83 | if (!canCatch(seq, seqlen, moveDistance, evePoint, low) && canCatch(seq, seqlen, moveDistance, evePoint, high)) { |
84 | return high; |
85 | } |
86 | if (canCatch(seq, seqlen, moveDistance, evePoint, low) && canCatch(seq, seqlen, moveDistance, evePoint, high)) { |
87 | return low; |
88 | } |
89 | } |
90 | long long int mid = (high + low) / 2; |
91 | if (canCatch(seq, seqlen, moveDistance, evePoint, mid)) { |
92 | return binarySearch(seq, seqlen, moveDistance, evePoint, low, mid); |
93 | } |
94 | else { |
95 | return binarySearch(seq, seqlen, moveDistance, evePoint, mid, high); |
96 | } |
97 | } |
98 | /************************************************************** |
99 | Problem: 1254 |
100 | User: |
101 | Language: C++ |
102 | Result: Accepted |
103 | Time:0 ms |
104 | Memory:2780 kb |
105 | ****************************************************************/ |
1 | public class Main { |
2 | public static void main(String[] args) { |
3 | java.util.Scanner input = new java.util.Scanner(System.in); |
4 | int[] evePoint = {input.nextInt(), input.nextInt()}; |
5 | int[] nekoPoint = {input.nextInt(), input.nextInt()}; |
6 | int seqLength = input.nextInt(); |
7 | String sequence = input.next(); |
8 | input.close(); |
9 | if(nekoPoint[0]==evePoint[0] && nekoPoint[1]==evePoint[1]) { |
10 | System.out.printf("%d\n", 0); |
11 | return; |
12 | } |
13 | long[][] seq = new long[seqLength][2]; |
14 | seq[0] = move(new long[]{nekoPoint[0], nekoPoint[1]}, sequence.charAt(0)); |
15 | for(int i = 1; i < seqLength; i++) { |
16 | seq[i] = move(seq[i-1], sequence.charAt(i)); |
17 | } |
18 | |
19 | long[] moveDistance = {seq[seqLength-1][0]-nekoPoint[0], seq[seqLength-1][1]-nekoPoint[1]}; |
20 | |
21 | if(!canCatch(seq, moveDistance, evePoint, 1000000000000000000L)) { |
22 | System.out.printf("%d\n", -1); |
23 | return; |
24 | } |
25 | |
26 | System.out.printf("%d\n", binarySearch(seq, moveDistance, evePoint, 0, 1000000000000000000L) + 1); |
27 | } |
28 | |
29 | private static long[] move(long[] point, char direction) { |
30 | long[] p = point.clone(); |
31 | switch(direction) { |
32 | case 'R': { |
33 | p[0]++; |
34 | break; |
35 | } |
36 | case 'L': { |
37 | p[0]--; |
38 | break; |
39 | } |
40 | case 'U': { |
41 | p[1]++; |
42 | break; |
43 | } |
44 | case 'D': { |
45 | p[1]--; |
46 | break; |
47 | } |
48 | default: |
49 | } |
50 | return p; |
51 | } |
52 | |
53 | private static long calDistance(long p00, long p01, int[] p1) { |
54 | return Math.abs(p00 - p1[0]) + Math.abs(p01 - p1[1]); |
55 | } |
56 | |
57 | private static boolean canCatch(long[][] seq, long[] moveDistance, int[] evePoint, long time) { |
58 | return time + 1 >= calDistance( |
59 | seq[(int)(time%seq.length)][0] + time/seq.length*moveDistance[0], |
60 | seq[(int)(time%seq.length)][1] + time/seq.length*moveDistance[1], |
61 | evePoint |
62 | ); |
63 | } |
64 | |
65 | private static long binarySearch(long[][] seq, long[] moveDistance, int[] evePoint, long low, long high) { |
66 | if(high - low <= 1) { |
67 | if(!canCatch(seq, moveDistance, evePoint, low) && canCatch(seq, moveDistance, evePoint, high)) { |
68 | return high; |
69 | } |
70 | if(canCatch(seq, moveDistance, evePoint, low) && canCatch(seq, moveDistance, evePoint, high)) { |
71 | return low; |
72 | } |
73 | } |
74 | long mid = (high+low) / 2; |
75 | if(canCatch(seq, moveDistance, evePoint, mid)) { |
76 | return binarySearch(seq, moveDistance, evePoint, low, mid); |
77 | } |
78 | else { |
79 | return binarySearch(seq, moveDistance, evePoint, mid, high); |
80 | } |
81 | } |
82 | } |
83 | |
84 | /************************************************************** |
85 | Problem: 1254 |
86 | User: |
87 | Language: Java |
88 | Result: Accepted |
89 | Time:328 ms |
90 | Memory:19356 kb |
91 | ****************************************************************/ |
Problem F: [Bonus] Suffix Zero
Description
Neko thinks math is interesting but he has got stuck at a math problem, so he asks you for help.
Find the number of consecutive zeros at the end of n!n! (in decimal representation).
Input
The first line contains a single integer $T$($1≤T≤10^6$) —— the number of test case.
The $2^{nd}$ line to the $(n+1)^{th}$ line, each line contains a single integer $n$($0≤n≤1018$).
Output
Print the number of consecutive zeros at the end of $n!4.
Sample Input
1 | 3 |
2 | 5 |
3 | 3 |
4 | 10 |
Sample Output
1 | 1 |
2 | 0 |
3 | 2 |
HINT
For the third case, 10! = 3628800, which have 2 consecutive zeros at the end.
Code
1 |
|
2 | |
3 | using namespace std; |
4 | |
5 | |
6 | int read_int() { |
7 | char r; |
8 | bool start = false, neg = false; |
9 | int ret = 0; |
10 | while (true) { |
11 | r = getchar(); |
12 | if ((r - '0' < 0 || r - '0'>9) && r != '-' && !start) { |
13 | continue; |
14 | } |
15 | if ((r - '0' < 0 || r - '0'>9) && r != '-' && start) { |
16 | break; |
17 | } |
18 | if (start)ret *= 10; |
19 | start = true; |
20 | if (r == '-')neg = true; |
21 | else ret += r - '0'; |
22 | } |
23 | if (!neg) |
24 | return ret; |
25 | else |
26 | return -ret; |
27 | } |
28 | |
29 | |
30 | long long read_ll() { |
31 | char r; |
32 | bool start = false, neg = false; |
33 | long long ret = 0; |
34 | while (true) { |
35 | r = getchar(); |
36 | if ((r - '0' < 0 || r - '0'>9) && r != '-' && !start) { |
37 | continue; |
38 | } |
39 | if ((r - '0' < 0 || r - '0'>9) && r != '-' && start) { |
40 | break; |
41 | } |
42 | if (start)ret *= 10; |
43 | start = true; |
44 | if (r == '-')neg = true; |
45 | else ret += r - '0'; |
46 | } |
47 | if (!neg) |
48 | return ret; |
49 | else |
50 | return -ret; |
51 | } |
52 | |
53 | |
54 | long long func(long long n) { |
55 | if (n < 5) return 0; |
56 | return n / 5 + func(n / 5); |
57 | } |
58 | |
59 | |
60 | int main() { |
61 | int times = read_int(); |
62 | while (times-- > 0) { |
63 | long long n = read_ll(); |
64 | printf("%lld\n", func(n - n % 5)); |
65 | } |
66 | return 0; |
67 | } |
68 | |
69 | /************************************************************** |
70 | Problem: 1255 |
71 | User: |
72 | Language: C++ |
73 | Result: Accepted |
74 | Time:368 ms |
75 | Memory:1092 kb |
76 | ****************************************************************/ |
Lab2_Sorting
Problem A: Interesting number
Description
You are given $n$($n≥3$) numbers. Lanran thinks that the third largest number is interesting, but lanran does not like multiple numbers with the same value. If there are more than one numbers equal to the third largest number, please output ‘wa’ (without quotes), otherwise please print it out.
Input
There are multiple testcases.
The first line of the input contains a single integer $T$($1≤T≤10$), indicates the number of the testcases.
Then T testcases follow:
For each testcase, the first line contains a single integer $n$($3≤n≤100$).
The second line contains n integers $a_1,a_2,…,a_n$($0≤a_i≤100$), separated by a space.
Output
Output T integers for the answers of T testcases.
Sample Input
1 | 7 |
2 | 3 |
3 | 1 1 1 |
4 | 4 |
5 | 2 3 3 3 |
6 | 5 |
7 | 1 2 3 4 2 |
8 | 3 |
9 | 3 1 2 |
10 | 4 |
11 | 4 9 13 13 |
12 | 5 |
13 | 20 1 20 1 9 |
14 | 10 |
15 | 6 7 8 9 10 1 2 3 4 5 |
Sample Output
1 | wa |
2 | wa |
3 | wa |
4 | 1 |
5 | 9 |
6 | 9 |
7 | 8 |
Code
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | void insertSort(int* array, int left, int right); |
8 | void swap(int* a, int* b); |
9 | int generatePivot(int* array, int left, int right); |
10 | void quickSort(int* array, int left, int right); |
11 | |
12 | int main() { |
13 | int times; |
14 | std::scanf("%i", ×); |
15 | while (times-- > 0) { |
16 | int length; |
17 | std::scanf("%i", &length); |
18 | int* list = new int[length]; |
19 | for (int i = 0; i < length; i++) { |
20 | std::scanf("%i", &list[i]); |
21 | } |
22 | quickSort(list, 0, length-1); |
23 | |
24 | if (list[length - 2] != list[length - 3] && (length == 3 || length > 3 && list[length - 4] != list[length - 3])) { |
25 | printf("%i\n", list[length - 3]); |
26 | continue; |
27 | } |
28 | printf("wa\n"); |
29 | } |
30 | return 0; |
31 | } |
32 | |
33 | void insertSort(int* array, int left, int right) { |
34 | for (int i = left + 1; i <= right; i++) { |
35 | auto key = array[i]; |
36 | auto j = i - 1; |
37 | while (j >= 0 && key < array[j]) { |
38 | array[j + 1] = array[j]; |
39 | j--; |
40 | } |
41 | array[j + 1] = key; |
42 | } |
43 | } |
44 | |
45 | void swap(int* a, int* b) { |
46 | int temp; |
47 | temp = *a; |
48 | *a = *b; |
49 | *b = temp; |
50 | } |
51 | |
52 | int generatePivot(int* array, int left, int right) { |
53 | auto mid = (left + right) >> 1; |
54 | if (array[left] > array[mid]) swap(&array[left], &array[mid]); |
55 | if (array[left] > array[right]) swap(&array[left], &array[right]); |
56 | if (array[mid] > array[right]) swap(&array[mid], &array[right]); |
57 | swap(&array[mid], &array[right - 1]); |
58 | return array[right - 1]; |
59 | } |
60 | |
61 | void quickSort(int* array, int left, int right) { |
62 | if (left >= right) return; |
63 | if (right - left < 10) { |
64 | insertSort(array, left, right); |
65 | return; |
66 | } |
67 | auto pivot = generatePivot(array, left, right); |
68 | int i = left, j = right - 1; |
69 | while (true) { |
70 | while (array[++i] < pivot); |
71 | while (array[--j] > pivot); |
72 | if (i < j) swap(&array[i], &array[j]); |
73 | else break; |
74 | } |
75 | swap(&array[i], &array[right - 1]); |
76 | quickSort(array, left, i - 1); |
77 | quickSort(array, i + 1, right); |
78 | } |
79 | /************************************************************** |
80 | Problem: 1218 |
81 | User: |
82 | Language: C++ |
83 | Result: Accepted |
84 | Time:0 ms |
85 | Memory:1216 kb |
86 | ****************************************************************/ |
1 |
|
2 |
|
3 | |
4 | |
5 | int cmpfunc (const void * a, const void * b) { |
6 | return *(int*)a - *(int*)b; |
7 | } |
8 | |
9 | int main() { |
10 | int times; |
11 | scanf("%i", ×); |
12 | while (times-- > 0) { |
13 | int length; |
14 | scanf("%i", &length); |
15 | int list[100]; |
16 | for (int i = 0; i < length; i++) { |
17 | scanf("%i", &list[i]); |
18 | } |
19 | qsort(list, length, sizeof(int), cmpfunc); |
20 | |
21 | if (list[length - 2] != list[length - 3] && (length == 3 || length > 3 && list[length - 4] != list[length - 3])) { |
22 | printf("%i\n", list[length - 3]); |
23 | continue; |
24 | } |
25 | printf("wa\n"); |
26 | } |
27 | return 0; |
28 | } |
29 | |
30 | /************************************************************** |
31 | Problem: 1218 |
32 | User: |
33 | Language: C |
34 | Result: Accepted |
35 | Time:0 ms |
36 | Memory:1092 kb |
37 | ****************************************************************/ |
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | |
8 | int main() { |
9 | int times; |
10 | std::scanf("%i", ×); |
11 | while (times-- > 0) { |
12 | int length; |
13 | std::scanf("%i", &length); |
14 | int* list = new int[length]; |
15 | for (int i = 0; i < length; i++) { |
16 | std::scanf("%i", &list[i]); |
17 | } |
18 | std::sort(list, list + length); |
19 | |
20 | if (list[length - 2] != list[length - 3] && (length == 3 || length > 3 && list[length - 4] != list[length - 3])) { |
21 | printf("%i\n", list[length - 3]); |
22 | continue; |
23 | } |
24 | printf("wa\n"); |
25 | } |
26 | } |
27 | |
28 | /************************************************************** |
29 | Problem: 1218 |
30 | User: |
31 | Language: C++ |
32 | Result: Accepted |
33 | Time:0 ms |
34 | Memory:1220 kb |
35 | ****************************************************************/ |
Problem B: Lucky number
Description
Given $n$ numbers $a_1,a_2,…,a_n$ and an integer $k$, Lanran thinks that the $k^{th}$ smallest number is a lucky number. Please tell him what is the value of the lucky number.
Input
The first line of the input contains two integers $n,k$($1≤n≤1 000 000,1≤k≤n$).
The second line contains $n$ integers $a_1,a_2,…,a_n$($0≤ai≤1 000 000$).
Output
Output one integer indicates the answer.
Sample Input
1 | 5 3 |
2 | 1 4 2 6 8 |
Sample Output
1 | 4 |
Code
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | void insertSort(int* array, int left, int right); |
8 | void swap(int* a, int* b); |
9 | int generatePivot(int* array, int left, int right); |
10 | void quickSort(int* array, int left, int right); |
11 | |
12 | int main() { |
13 | int length; |
14 | std::scanf("%i", &length); |
15 | int kth; |
16 | std::scanf("%i", &kth); |
17 | int* list = new int[length]; |
18 | for (int i = 0; i < length; i++) { |
19 | std::scanf("%i", &list[i]); |
20 | } |
21 | quickSort(list, 0, length-1); |
22 | |
23 | printf("%i", list[kth-1]); |
24 | return 0; |
25 | } |
26 | |
27 | void insertSort(int* array, int left, int right) { |
28 | for (int i = left + 1; i <= right; i++) { |
29 | auto key = array[i]; |
30 | auto j = i - 1; |
31 | while (j >= 0 && key < array[j]) { |
32 | array[j + 1] = array[j]; |
33 | j--; |
34 | } |
35 | array[j + 1] = key; |
36 | } |
37 | } |
38 | |
39 | void swap(int* a, int* b) { |
40 | int temp; |
41 | temp = *a; |
42 | *a = *b; |
43 | *b = temp; |
44 | } |
45 | |
46 | int generatePivot(int* array, int left, int right) { |
47 | auto mid = (left + right) >> 1; |
48 | if (array[left] > array[mid]) swap(&array[left], &array[mid]); |
49 | if (array[left] > array[right]) swap(&array[left], &array[right]); |
50 | if (array[mid] > array[right]) swap(&array[mid], &array[right]); |
51 | swap(&array[mid], &array[right - 1]); |
52 | return array[right - 1]; |
53 | } |
54 | |
55 | void quickSort(int* array, int left, int right) { |
56 | if (left >= right) return; |
57 | if (right - left < 10) { |
58 | insertSort(array, left, right); |
59 | return; |
60 | } |
61 | auto pivot = generatePivot(array, left, right); |
62 | int i = left, j = right - 1; |
63 | while (true) { |
64 | while (array[++i] < pivot); |
65 | while (array[--j] > pivot); |
66 | if (i < j) swap(&array[i], &array[j]); |
67 | else break; |
68 | } |
69 | swap(&array[i], &array[right - 1]); |
70 | quickSort(array, left, i - 1); |
71 | quickSort(array, i + 1, right); |
72 | } |
73 | /************************************************************** |
74 | Problem: 1256 |
75 | User: |
76 | Language: C++ |
77 | Result: Accepted |
78 | Time:372 ms |
79 | Memory:5124 kb |
80 | ****************************************************************/ |
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | |
8 | int main() { |
9 | int length; |
10 | std::scanf("%i", &length); |
11 | int kth; |
12 | std::scanf("%i", &kth); |
13 | int* list = new int[length]; |
14 | for (int i = 0; i < length; i++) { |
15 | std::scanf("%i", &list[i]); |
16 | } |
17 | std::sort(list, list + length); |
18 | |
19 | printf("%i", list[kth-1]); |
20 | return 0; |
21 | } |
22 | |
23 | /************************************************************** |
24 | Problem: 1256 |
25 | User: |
26 | Language: C++ |
27 | Result: Accepted |
28 | Time:408 ms |
29 | Memory:5128 kb |
30 | ****************************************************************/ |
1 |
|
2 |
|
3 | |
4 | int compare (const void * a, const void * b) { |
5 | return *(int*)a - *(int*)b; |
6 | } |
7 | |
8 | int main() { |
9 | int length; |
10 | scanf("%i", &length); |
11 | int kth; |
12 | scanf("%i", &kth); |
13 | int list[1000000]; |
14 | for (int i = 0; i < length; i++) { |
15 | scanf("%i", &list[i]); |
16 | } |
17 | qsort(list, length, sizeof(int), compare); |
18 | |
19 | printf("%i\n", list[kth-1]); |
20 | return 0; |
21 | } |
22 | |
23 | /************************************************************** |
24 | Problem: 1256 |
25 | User: |
26 | Language: C |
27 | Result: Accepted |
28 | Time:212 ms |
29 | Memory:8780 kb |
30 | ****************************************************************/ |
Problem C: Only 3-sum
Description
Given $n$ numbers $a_1,a_2,…,a_n$ and a lucky number mm, please output the number of triple $(i,j,k)$,satisfying$a_i+a_j+a_k=m$($i<j<k$).
Input
The first line of the input contains two integers $n,m$($1≤n≤3000,1≤m≤1 000 000 000$).
The second line contains $n$ integers $a_1,a_2,…,a_n$($1≤a_i≤1 000 000 000$).
Output
Output one integer indicates the answer.
Sample Input
1 | 4 9 |
2 | 1 3 5 3 |
Sample Output
1 | 2 |
Code
1 |
|
2 |
|
3 |
|
4 |
|
5 | |
6 | using namespace std; |
7 | |
8 | int list0[3000]; |
9 | int num[3000] = { 0 }; |
10 | map<int, int> content; |
11 | |
12 | int binarySearch(int* array, int low, int high, int key); |
13 | void insertSort(int* array, int left, int right); |
14 | void swap(int* a, int* b); |
15 | int generatePivot(int* array, int left, int right); |
16 | void quickSort(int* array, int left, int right); |
17 | |
18 | int main() { |
19 | int length; |
20 | scanf("%i", &length); |
21 | int sum; |
22 | scanf("%i", &sum); |
23 | for (int i = 0; i < length; i++) scanf("%i", &list0[i]); |
24 | quickSort(list0, 0, length-1); |
25 | num[0] = 1; |
26 | for (int i = 1; i < length; i++) { |
27 | if (list0[i] == list0[i - 1]) { |
28 | num[i] = num[i - 1] + 1; |
29 | } |
30 | else { |
31 | num[i] = 1; |
32 | content.insert(pair<int, int>(list0[i - 1], i - 1)); |
33 | } |
34 | } |
35 | content.insert(pair<int, int>(list0[length - 1], length - 1)); |
36 | |
37 | long long int time = 0; |
38 | for (int i = 0; i < length; i++) { |
39 | for (int j = i + 1; j < length; j++) { |
40 | int det = sum - list0[i] - list0[j]; |
41 | if (det > list0[length - 1]) continue; |
42 | if (det < list0[j] || det < 1) break; |
43 | int index = binarySearch(list0, j + 1, length - 1, det); |
44 | if (index != -1) { |
45 | if (list0[index] == list0[j]) { |
46 | time += num[content[list0[index]]] - num[j]; |
47 | } |
48 | else { |
49 | time += num[content[list0[index]]]; |
50 | } |
51 | } |
52 | } |
53 | if (list0[i] >= sum) break; |
54 | } |
55 | printf("%lli\n", time); |
56 | return 0; |
57 | } |
58 | |
59 | int binarySearch(int* array, int low, int high, int key) { |
60 | if (low > high) return -1; |
61 | int mid = (low + high) / 2; |
62 | if (array[mid] == key) return mid; |
63 | else if (array[mid] < key) return binarySearch(array, mid + 1, high, key); |
64 | else return binarySearch(array, low, mid - 1, key); |
65 | } |
66 | |
67 | |
68 | void insertSort(int* array, int left, int right) { |
69 | for (int i = left + 1; i <= right; i++) { |
70 | auto key = array[i]; |
71 | auto j = i - 1; |
72 | while (j >= 0 && key < array[j]) { |
73 | array[j + 1] = array[j]; |
74 | j--; |
75 | } |
76 | array[j + 1] = key; |
77 | } |
78 | } |
79 | |
80 | void swap(int* a, int* b) { |
81 | int temp; |
82 | temp = *a; |
83 | *a = *b; |
84 | *b = temp; |
85 | } |
86 | |
87 | int generatePivot(int* array, int left, int right) { |
88 | auto mid = (left + right) >> 1; |
89 | if (array[left] > array[mid]) swap(&array[left], &array[mid]); |
90 | if (array[left] > array[right]) swap(&array[left], &array[right]); |
91 | if (array[mid] > array[right]) swap(&array[mid], &array[right]); |
92 | swap(&array[mid], &array[right - 1]); |
93 | return array[right - 1]; |
94 | } |
95 | |
96 | void quickSort(int* array, int left, int right) { |
97 | if (left >= right) return; |
98 | if (right - left < 10) { |
99 | insertSort(array, left, right); |
100 | return; |
101 | } |
102 | auto pivot = generatePivot(array, left, right); |
103 | int i = left, j = right - 1; |
104 | while (true) { |
105 | while (array[++i] < pivot); |
106 | while (array[--j] > pivot); |
107 | if (i < j) swap(&array[i], &array[j]); |
108 | else break; |
109 | } |
110 | swap(&array[i], &array[right - 1]); |
111 | quickSort(array, left, i - 1); |
112 | quickSort(array, i + 1, right); |
113 | } |
114 | /************************************************************** |
115 | Problem: 1258 |
116 | User: |
117 | Language: C++ |
118 | Result: Accepted |
119 | Time:264 ms |
120 | Memory:1280 kb |
121 | ****************************************************************/ |
1 |
|
2 |
|
3 |
|
4 |
|
5 | |
6 | using namespace std; |
7 | |
8 | int list0[3000]; |
9 | int num[3000] = { 0 }; |
10 | map<int, int> content; |
11 | |
12 | int binarySearch(int* array, int low, int high, int key); |
13 | |
14 | int main() { |
15 | int length; |
16 | scanf("%i", &length); |
17 | int sum; |
18 | scanf("%i", &sum); |
19 | for (int i = 0; i < length; i++) scanf("%i", &list0[i]); |
20 | std::sort(list0, list0 + length); |
21 | num[0] = 1; |
22 | for (int i = 1; i < length; i++) { |
23 | if (list0[i] == list0[i - 1]) { |
24 | num[i] = num[i - 1] + 1; |
25 | } |
26 | else { |
27 | num[i] = 1; |
28 | content.insert(pair<int, int>(list0[i - 1], i - 1)); |
29 | } |
30 | } |
31 | content.insert(pair<int, int>(list0[length - 1], length - 1)); |
32 | |
33 | long long int time = 0; |
34 | for (int i = 0; i < length; i++) { |
35 | for (int j = i + 1; j < length; j++) { |
36 | int det = sum - list0[i] - list0[j]; |
37 | if (det > list0[length - 1]) continue; |
38 | if (det < list0[j] || det < 1) break; |
39 | int index = binarySearch(list0, j + 1, length - 1, det); |
40 | if (index != -1) { |
41 | if (list0[index] == list0[j]) { |
42 | time += num[content[list0[index]]] - num[j]; |
43 | } |
44 | else { |
45 | time += num[content[list0[index]]]; |
46 | } |
47 | } |
48 | } |
49 | if (list0[i] >= sum) break; |
50 | } |
51 | printf("%lli\n", time); |
52 | return 0; |
53 | } |
54 | |
55 | int binarySearch(int* array, int low, int high, int key) { |
56 | if (low > high) return -1; |
57 | int mid = (low + high) / 2; |
58 | if (array[mid] == key) return mid; |
59 | else if (array[mid] < key) return binarySearch(array, mid + 1, high, key); |
60 | else return binarySearch(array, low, mid - 1, key); |
61 | } |
62 | |
63 | /************************************************************** |
64 | Problem: 1258 |
65 | User: |
66 | Language: C++ |
67 | Result: Accepted |
68 | Time:256 ms |
69 | Memory:1284 kb |
70 | ****************************************************************/ |
Problem D: Vinceblack’s store
Description
Vinceblack has a candy store with $n$ candies in a row, and the volume of each candy is $v_i$. To make the candy store more beautiful, Vince wants to move some candies to make them sorted in increasing order in volume. However, he can only exchange two adjacent candies, and the cost of the movement equals to the sum of volumes. Now Vince wants you to tell him what is the minimum cost to sort the candies.
Input
The first line of the input contains one integer $n$($1≤n≤100 000$).
The second line contains $n$ integers $v_1,v_2,…,v_n$($1≤vi≤100 000 000$).
It is guaranteed that the volume of all the candies are distinct.
Output
Output one integer indicates the minimum cost.
Sample Input
1 | 3 |
2 | 2 3 1 |
Sample Output
1 | 7 |
HINT
2 3 1 -> 2 1 3 cost: 4
2 1 3 -> 1 2 3 cost: 3
total cost: 4+3=7
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | int array[100000]; |
7 | long long int sum[100000]; |
8 | int temp[100000]; |
9 | long long int cost = 0; |
10 | |
11 | void mergeSort(int low, int mid, int high); |
12 | void mergeSort(int low, int high); |
13 | |
14 | int main() { |
15 | int length; |
16 | scanf("%i", &length); |
17 | for (int i = 0; i < length; i++) { |
18 | scanf("%i", &array[i]); |
19 | sum[i] = array[i]; |
20 | } |
21 | mergeSort(0, length - 1); |
22 | printf("%lli", cost); |
23 | return 0; |
24 | } |
25 | |
26 | void mergeSort(int low, int mid, int high) { |
27 | sum[high] = sum[mid] + sum[high]; |
28 | long midSum = sum[mid]; |
29 | int i = low, j = mid + 1, k = 0; |
30 | while (i <= mid && j <= high) { |
31 | if (array[i] > array[j]) { |
32 | cost += (long long int)array[j] * ((long long int)mid - i + 1); |
33 | cost += midSum; |
34 | temp[k++] = array[j++]; |
35 | } |
36 | else { |
37 | midSum -= array[i]; |
38 | temp[k++] = array[i++]; |
39 | } |
40 | } |
41 | while (i <= mid) temp[k++] = array[i++]; |
42 | while (j <= high) temp[k++] = array[j++]; |
43 | for (k = 0; k < high - low + 1; k++) array[low + k] = temp[k]; |
44 | } |
45 | |
46 | void mergeSort(int low, int high) { |
47 | if (low >= high) return; |
48 | int mid = (low + high) >> 1; |
49 | mergeSort(low, mid); |
50 | mergeSort(mid + 1, high); |
51 | mergeSort(low, mid, high); |
52 | } |
53 | |
54 | /************************************************************** |
55 | Problem: 1257 |
56 | User: |
57 | Language: C++ |
58 | Result: Accepted |
59 | Time:40 ms |
60 | Memory:2652 kb |
61 | ****************************************************************/ |
1 | import java.util.Scanner; |
2 | |
3 | public class Main { |
4 | private static int[] array; |
5 | private static long cost; |
6 | public static void main(String[] args) { |
7 | Scanner input = new Scanner(System.in); |
8 | int len = input.nextInt(); |
9 | array = new int[len]; |
10 | for(int i = 0; i < len; i++) array[i] = input.nextInt(); |
11 | input.close(); |
12 | mergeSort(0, len-1); |
13 | System.out.printf("%d\n", cost); |
14 | } |
15 | |
16 | private static void mergeSort(int low, int mid, int high) { |
17 | int[] temp = new int[high - low + 1]; |
18 | int i = low, j = mid + 1, k = 0; |
19 | while(i <= mid && j <= high) { |
20 | if (array[i] > array[j]) { |
21 | cost += (long)array[j] * (mid - i + 1); |
22 | for(int t = i; t <= mid; t++) cost += array[t]; |
23 | temp[k++] = array[j++]; |
24 | } |
25 | else { |
26 | temp[k++] = array[i++]; |
27 | } |
28 | } |
29 | while(i <= mid) temp[k++] = array[i++]; |
30 | while(j <= high) temp[k++] = array[j++]; |
31 | for(int t = 0; t < high - low + 1; t++) array[low + t] = temp[t]; |
32 | } |
33 | |
34 | private static void mergeSort(int low, int high) { |
35 | if (low >= high) return; |
36 | int mid = (low + high) >> 1; |
37 | mergeSort(low, mid); |
38 | mergeSort(mid + 1, high); |
39 | mergeSort(low, mid, high); |
40 | } |
41 | } |
42 | |
43 | /************************************************************** |
44 | Problem: 1257 |
45 | User: |
46 | Language: Java |
47 | Result: Accepted |
48 | Time:2136 ms |
49 | Memory:42024 kb |
50 | ****************************************************************/ |
1 | import java.util.Scanner; |
2 | |
3 | public class Main { |
4 | private static int[] array; |
5 | private static long[] sum; |
6 | private static long cost; |
7 | public static void main(String[] args) { |
8 | Scanner input = new Scanner(System.in); |
9 | int len = input.nextInt(); |
10 | array = new int[len]; |
11 | sum = new long[len]; |
12 | for(int i = 0; i < len; i++) sum[i] = array[i] = input.nextInt(); |
13 | input.close(); |
14 | mergeSort(0, len-1); |
15 | System.out.printf("%d\n", cost); |
16 | } |
17 | |
18 | private static void mergeSort(int low, int mid, int high) { |
19 | sum[high] = sum[mid] + sum[high]; |
20 | long midSum = sum[mid]; |
21 | int[] temp = new int[high - low + 1]; |
22 | int i = low, j = mid + 1, k = 0; |
23 | while(i <= mid && j <= high) { |
24 | if (array[i] > array[j]) { |
25 | cost += midSum; |
26 | cost += (long)array[j] * (mid - i + 1); |
27 | //for(int t = i; t <= mid; t++) cost += array[t]; |
28 | temp[k++] = array[j++]; |
29 | } |
30 | else { |
31 | midSum -= array[i]; |
32 | temp[k++] = array[i++]; |
33 | } |
34 | } |
35 | while(i <= mid) temp[k++] = array[i++]; |
36 | while(j <= high) temp[k++] = array[j++]; |
37 | for(int t = 0; t < high - low + 1; t++) array[low + t] = temp[t]; |
38 | } |
39 | |
40 | private static void mergeSort(int low, int high) { |
41 | if (low >= high) return; |
42 | int mid = (low + high) >> 1; |
43 | mergeSort(low, mid); |
44 | mergeSort(mid + 1, high); |
45 | mergeSort(low, mid, high); |
46 | } |
47 | } |
48 | |
49 | /************************************************************** |
50 | Problem: 1257 |
51 | User: |
52 | Language: Java |
53 | Result: Accepted |
54 | Time:684 ms |
55 | Memory:41692 kb |
56 | ****************************************************************/ |
Problem E: Excellent power
Description
In the tale, there was a great wizard at SUSTech called SUSTechDaFaShi with excellent power. With his great power, DFS led a scourge army with $n$ ultimate soldiers. Each soldier has 2 attributes, hp and attack. What’s more, DFS can cast at most $p$ times of spell1 to make one soldier double its hp, and at most $q$ times of spell2 to make one soldier’s attack equal to its hp. DFS wants to know the maximum sum of the attack of all his soldiers after casting two kinds of spells.
Input
The first line of the input contains three integers $n,p,q$($1≤n≤200 000,0≤p≤20,0≤q≤200 000$).
Then $n$ lines follow, each line contains two integers $hp_i,attack_i$($1≤hp_i,attack_i≤1 000 000 000$), indicates the hp and attack of the $i^{th}$ soldier.
Output
Print one single integer, the sum of the attack of all the soldiers.
Sample Input
1 | 2 1 1 |
2 | 10 8 |
3 | 6 1 |
Sample Output
1 | 21 |
HINT
DFS can choose not to cast any spell.
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | long long soldiers[200000][2]; |
7 | long long tempS[200000][2]; |
8 | long long profit[200000]; |
9 | long long temp[200000]; |
10 | long long attack; |
11 | |
12 | void mergeSort(long long* array, int low, int high); |
13 | int findMax(long long* array, int len); |
14 | |
15 | int main() { |
16 | int soldierNum, divineSpirit, innerFire; |
17 | scanf("%i %i %i", &soldierNum, &divineSpirit, &innerFire); |
18 | for (int i = 0; i < soldierNum; i++) scanf("%lli %lli", &soldiers[i][0], &soldiers[i][1]); |
19 | if (innerFire == 0) { |
20 | for (int i = 0; i < soldierNum; i++) attack += soldiers[i][1]; |
21 | printf("%lli\n", attack); |
22 | return 0; |
23 | } |
24 | for (int i = 0; i < soldierNum; i++) profit[i] = soldiers[i][0] - soldiers[i][1]; |
25 | mergeSort(profit, 0, soldierNum - 1); |
26 | long long times = 1; |
27 | times <<= divineSpirit; |
28 | int lastIF = innerFire; |
29 | int last = 0; |
30 | auto atk = soldiers[0][1]; |
31 | for (int i = 0, iF = innerFire; i < soldierNum && iF > 0; i++, iF--, lastIF--) { |
32 | if (profit[i] > 0) { |
33 | last = i; |
34 | atk = soldiers[i][1]; |
35 | soldiers[i][1] = soldiers[i][0]; |
36 | } |
37 | else break; |
38 | } |
39 | for (int i = 0; i < soldierNum; i++) { |
40 | profit[i] = soldiers[i][0] * times - soldiers[i][1]; |
41 | if (i >= innerFire - lastIF && profit[last] > 0 && lastIF == 0) { |
42 | profit[i] = soldiers[i][0] * times - soldiers[i][1] - soldiers[last][0] + atk; |
43 | } |
44 | } |
45 | auto index = findMax(profit, soldierNum); |
46 | if (index > last && profit[last] > 0 && lastIF == 0) soldiers[last][1] = atk; |
47 | if (profit[index] > 0) soldiers[index][1] = soldiers[index][0] * times; |
48 | for (int i = 0; i < soldierNum; i++) attack += soldiers[i][1]; |
49 | printf("%lli\n", attack); |
50 | return 0; |
51 | } |
52 | |
53 | bool comparator(long long a, long long b) { |
54 | return a >= b; |
55 | } |
56 | |
57 | void copyArray(int indexA, long long* A, long long As[][2], int indexB, long long* B, long long Bs[][2]) { |
58 | A[indexA] = B[indexB]; |
59 | As[indexA][0] = Bs[indexB][0]; |
60 | As[indexA][1] = Bs[indexB][1]; |
61 | } |
62 | |
63 | void mergeSort(long long* array, int low, int mid, int high) { |
64 | int i = low, j = mid + 1, k = 0; |
65 | while (i <= mid && j <= high) { |
66 | if (comparator(array[i], array[j])) copyArray(k++, temp, tempS, i++, array, soldiers); |
67 | else copyArray(k++, temp, tempS, j++, array, soldiers); |
68 | } |
69 | while (i <= mid) copyArray(k++, temp, tempS, i++, array, soldiers); |
70 | while (j <= high) copyArray(k++, temp, tempS, j++, array, soldiers); |
71 | for (k = 0; k < high - low + 1; k++) copyArray(low + k, array, soldiers, k, temp, tempS); |
72 | } |
73 | |
74 | void mergeSort(long long* array, int low, int high) { |
75 | if (low >= high) return; |
76 | auto mid = (low + high) >> 1; |
77 | mergeSort(array, low, mid); |
78 | mergeSort(array, mid + 1, high); |
79 | mergeSort(array, low, mid, high); |
80 | } |
81 | |
82 | int findMax(long long* array, int len) { |
83 | auto max = array[0]; |
84 | int index = 0; |
85 | for (int i = 1; i < len; i++) { |
86 | if (array[i] > max) { |
87 | max = array[i]; |
88 | index = i; |
89 | } |
90 | } |
91 | return index; |
92 | } |
93 | /************************************************************** |
94 | Problem: 1221 |
95 | User: |
96 | Language: C++ |
97 | Result: Accepted |
98 | Time:220 ms |
99 | Memory:10464 kb |
100 | ****************************************************************/ |
Problem F: YYJ’s magic beads
Description
YYJ has many magic beads with two colors, red and blue. If a red bead is on the left of a blue bead and they are next to each other, they will disappear and release 1 unit of magic power. YYJ has $n$ strings of beads, each string is consists of $a_i$ blue beads on the left and $b_i$ red beads on the right (To make sure they will disappear). Note that $a_i$ and $b_i$ can be zero.
YYJ now wants to connect these strings in some order and she is wondering how many units of magic power she can get at most.
Input
The first line contains an integer $T$, indicating the number of test cases. For each test case:
The first line contains an integer $n$($1≤n≤100 000$), indicating the number of string of beads.
Each of the next $n$ lines contains two integers $a_i,b_i$($1≤a_i+b_i≤10 000$).
It is guaranteed that $∑(a_i+b_i)≤500 000$.
Output
Output one integer, indicating the answer.
Sample Input
1 | 2 |
2 | 2 |
3 | 1 2 |
4 | 2 1 |
5 | 2 |
6 | 1 3 |
7 | 2 1 |
Sample Output
1 | 2 |
2 | 2 |
HINT
We use ‘R’ to denote red beads and ‘B’ to denote blue beads.
We have 2 strings: BRR, BBR at first.
The string after connection is: BRRBBR, which can gain 2 units of magic power.
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | int strings[100000][2]; |
7 | int temp[100000][2]; |
8 | |
9 | bool comparator(int* a, int* b); |
10 | void mergeSort(int array[][2], int low, int mid, int high); |
11 | void mergeSort(int array[][2], int low, int high); |
12 | |
13 | int main() { |
14 | int testCase; |
15 | scanf("%i", &testCase); |
16 | while (testCase-- > 0) { |
17 | int stringNum; |
18 | long long int mana = 0; |
19 | scanf("%i", &stringNum); |
20 | for (int i = 0; i < stringNum; i++) scanf("%i %i", &strings[i][0], &strings[i][1]); |
21 | mergeSort(strings, 0, stringNum - 1); |
22 | for (int i = 1; i < stringNum; i++) { |
23 | int temp = strings[i - 1][1] - strings[i][0]; |
24 | if (temp > 0) { |
25 | mana += strings[i][0]; |
26 | strings[i][1] += temp; |
27 | strings[i][0] = 0; |
28 | strings[i - 1][1] = 0; |
29 | } |
30 | else { |
31 | mana += strings[i - 1][1]; |
32 | strings[i - 1][0] -= temp; |
33 | strings[i][0] = 0; |
34 | strings[i - 1][1] = 0; |
35 | } |
36 | } |
37 | printf("%lli\n", mana); |
38 | } |
39 | return 0; |
40 | } |
41 | |
42 | bool comparator(int* a, int* b) { |
43 | if (a[0] < a[1]) { |
44 | if (b[0] < b[1]) return a[0] < b[0]; |
45 | else return true; |
46 | } |
47 | else { |
48 | if (b[0] < b[1]) return false; |
49 | else return a[1] > b[1]; |
50 | } |
51 | } |
52 | |
53 | void copyArray(int* a, int* b) { |
54 | a[0] = b[0]; |
55 | a[1] = b[1]; |
56 | } |
57 | |
58 | void mergeSort(int array[][2], int low, int mid, int high) { |
59 | int i = low, j = mid + 1, k = 0; |
60 | while (i <= mid && j <= high) { |
61 | if(comparator(array[i], array[j])) copyArray(temp[k++], array[i++]); |
62 | else copyArray(temp[k++], array[j++]); |
63 | } |
64 | while (i <= mid) copyArray(temp[k++], array[i++]); |
65 | while (j <= high) copyArray(temp[k++], array[j++]); |
66 | for (k = 0; k < high - low + 1; k++) copyArray(array[low + k], temp[k]); |
67 | } |
68 | |
69 | void mergeSort(int array[][2], int low, int high) { |
70 | if (low >= high) return; |
71 | int mid = (low + high) >> 1; |
72 | mergeSort(array, low, mid); |
73 | mergeSort(array, mid + 1, high); |
74 | mergeSort(array, low, mid, high); |
75 | } |
76 | |
77 | /************************************************************** |
78 | Problem: 1259 |
79 | User: |
80 | Language: C++ |
81 | Result: Accepted |
82 | Time:88 ms |
83 | Memory:2652 kb |
84 | ****************************************************************/ |
Lab3_Linked_List
Problem A: Add polynomials together
Description
As Narnal has learned in the class, a polynomial can be represented as a linked list, but he failed to add two given polynomials together. He asks you to help him to get the summation of two polynomials.
Input
First line will be a positive integer $T$, which is the number of test cases.
In each test case, the first line will be an integer $n$ for the number of terms of the first polynomial. Then the next $n$ lines will be the coefficients and exponents of the terms with the order of increasing exponents.
After $n+1$ lines, there will be an integer $m$ for the number of terms of the second polynomial. Then the next $m$ lines will be the coefficients and exponents of the terms with the order of increasing exponents.
After $n+m+2$ lines, there will be an integer $q$ denoting the number of queries. Then one line containing $q$ ascending numbers will follow, where each number $k$ represents a query for the coefficient of exponent of $k$.
$1≤T≤200,1≤n,m≤103,1≤q≤2×10^3,0≤k≤10^9$. The coefficients will be in range $[−104,104]$. The exponents will be in range $[0,109]$.
Output
For each case, output one line contains $q$ answers of the corresponding queries.
Sample Input
1 | 1 |
2 | 2 |
3 | 1 1 |
4 | 2 3 |
5 | 3 |
6 | 1 100 |
7 | 3 150 |
8 | 5 170 |
9 | 4 |
10 | 1 20 100 170 |
Sample Output
1 | 1 0 1 5 |
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | struct Node { |
7 | int coefficient; |
8 | int exponent; |
9 | Node* next; |
10 | }; |
11 | |
12 | class linkedList { |
13 | public: |
14 | Node* head, * tail, * last; |
15 | |
16 | linkedList() { |
17 | head = new Node; |
18 | last = head; |
19 | tail = new Node; |
20 | head->next = tail; |
21 | head->exponent = 0; |
22 | tail->exponent = -1; |
23 | } |
24 | |
25 | void addElement(int coefficient, int exponent) { |
26 | Node* temp = new Node; |
27 | temp->coefficient = coefficient; |
28 | temp->exponent = exponent; |
29 | temp->next = tail; |
30 | last->next = temp; |
31 | last = last->next; |
32 | } |
33 | }; |
34 | |
35 | int readInt(); |
36 | int queries[2000]; |
37 | |
38 | int main() { |
39 | int testCase = readInt(); |
40 | int terms; |
41 | int c; |
42 | int e; |
43 | while (testCase--) { |
44 | terms = readInt(); |
45 | linkedList polynomial0 = linkedList(); |
46 | while (terms--) { |
47 | c = readInt(); |
48 | e = readInt(); |
49 | polynomial0.addElement(c, e); |
50 | } |
51 | terms = readInt(); |
52 | linkedList polynomial1 = linkedList(); |
53 | while (terms--) { |
54 | c = readInt(); |
55 | e = readInt(); |
56 | polynomial1.addElement(c, e); |
57 | } |
58 | terms = readInt(); |
59 | bool isContinue = true; |
60 | for (int i = 0; i < terms; i++) queries[i] = readInt(); |
61 | linkedList p = linkedList(); |
62 | Node* temp0 = polynomial0.head->next; |
63 | Node* temp1 = polynomial1.head->next; |
64 | while (temp0 != NULL && temp1 != NULL) { |
65 | if (temp0->exponent == -1) { |
66 | if (temp1->exponent == -1) break; |
67 | p.addElement(temp1->coefficient, temp1->exponent); |
68 | temp1 = temp1->next; |
69 | } |
70 | else if (temp1->exponent == -1) { |
71 | if (temp0->exponent == -1) break; |
72 | p.addElement(temp0->coefficient, temp0->exponent); |
73 | temp0 = temp0->next; |
74 | } |
75 | else if (temp0->exponent > temp1->exponent) { |
76 | p.addElement(temp1->coefficient, temp1->exponent); |
77 | temp1 = temp1->next; |
78 | } |
79 | else if (temp0->exponent < temp1->exponent) { |
80 | p.addElement(temp0->coefficient, temp0->exponent); |
81 | temp0 = temp0->next; |
82 | } |
83 | else { |
84 | p.addElement(temp0->coefficient + temp1->coefficient, temp0->exponent); |
85 | temp0 = temp0->next; |
86 | temp1 = temp1->next; |
87 | } |
88 | } |
89 | Node* temp = p.head->next; |
90 | for (int i = 0; i < terms; i++) { |
91 | if (queries[i] > p.last->exponent) { |
92 | for (; i < terms; i++) printf("%d ", 0); |
93 | break; |
94 | } |
95 | for (; temp->exponent > -1; temp = temp->next) { |
96 | if (queries[i] == temp->exponent) { |
97 | printf("%d ", temp->coefficient); |
98 | break; |
99 | } |
100 | else if (queries[i] < temp->exponent) { |
101 | printf("%d ", 0); |
102 | break; |
103 | } |
104 | } |
105 | } |
106 | printf("\n"); |
107 | } |
108 | return 0; |
109 | } |
110 | |
111 | |
112 | int readInt() { |
113 | char r; |
114 | bool start = false, neg = false; |
115 | int ret = 0; |
116 | while (true) { |
117 | r = getchar(); |
118 | if ((r - '0' < 0 || r - '0' > 9) && r != '-' && !start) continue; |
119 | if ((r - '0' < 0 || r - '0' > 9) && r != '-' && start) break; |
120 | if (start) ret *= 10; |
121 | start = true; |
122 | if (r == '-')neg = true; |
123 | else ret += r - '0'; |
124 | } |
125 | if (!neg) |
126 | return ret; |
127 | else |
128 | return -ret; |
129 | } |
130 | |
131 | /************************************************************** |
132 | Problem: 1261 |
133 | User: |
134 | Language: C++ |
135 | Result: Accepted |
136 | Time:132 ms |
137 | Memory:24456 kb |
138 | ****************************************************************/ |
1 | import java.io.*; |
2 | import java.util.StringTokenizer; |
3 | |
4 | public class Main { |
5 | public static void main(String[] args) { |
6 | InputReader input = new InputReader(System.in); |
7 | PrintWriter out = new PrintWriter(System.out); |
8 | int testCase = input.nextInt(); |
9 | while(testCase-->0) { |
10 | int terms = input.nextInt(); |
11 | LinkedList polynomial0 = new LinkedList(); |
12 | while(terms-->0) polynomial0.addElement(input.nextInt(), input.nextInt()); |
13 | terms = input.nextInt(); |
14 | LinkedList polynomial1 = new LinkedList(); |
15 | while(terms-->0) polynomial1.addElement(input.nextInt(), input.nextInt()); |
16 | terms = input.nextInt(); |
17 | int[] queries = new int[terms]; |
18 | boolean isContinue = true; |
19 | for (int i = 0; i < terms; i++) queries[i] = input.nextInt(); |
20 | LinkedList p = new LinkedList(); |
21 | Node temp0 = polynomial0.head.next; |
22 | Node temp1 = polynomial1.head.next; |
23 | while (temp0!=null && temp1!=null) { |
24 | if(temp0.exponent==-1) { |
25 | if(temp1.exponent==-1) break; |
26 | p.addElement(temp1.coefficient, temp1.exponent); |
27 | temp1 = temp1.next; |
28 | } |
29 | else if(temp1.exponent==-1) { |
30 | if(temp0.exponent==-1) break; |
31 | p.addElement(temp0.coefficient, temp0.exponent); |
32 | temp0 = temp0.next; |
33 | } |
34 | else if(temp0.exponent > temp1.exponent) { |
35 | p.addElement(temp1.coefficient, temp1.exponent); |
36 | temp1 = temp1.next; |
37 | } |
38 | else if(temp0.exponent < temp1.exponent) { |
39 | p.addElement(temp0.coefficient, temp0.exponent); |
40 | temp0 = temp0.next; |
41 | } |
42 | else { |
43 | p.addElement(temp0.coefficient+temp1.coefficient, temp0.exponent); |
44 | temp0 = temp0.next; |
45 | temp1 = temp1.next; |
46 | } |
47 | } |
48 | Node temp = p.head.next; |
49 | for (int i = 0; i < terms; i++) { |
50 | if (queries[i] > p.last.exponent) { |
51 | for (; i < terms; i++) out.printf("%d ", 0); |
52 | break; |
53 | } |
54 | for (; temp.exponent > -1; temp = temp.next) { |
55 | if (queries[i] == temp.exponent) { |
56 | out.printf("%d ", temp.coefficient); |
57 | break; |
58 | } |
59 | else if (queries[i] < temp.exponent) { |
60 | out.printf("%d ", 0); |
61 | break; |
62 | } |
63 | } |
64 | } |
65 | out.println(); |
66 | } |
67 | out.close(); |
68 | } |
69 | |
70 | private static class Node { |
71 | int coefficient; |
72 | int exponent; |
73 | Node next; |
74 | |
75 | Node(int coefficient, int exponent) { |
76 | this.coefficient = coefficient; |
77 | this.exponent = exponent; |
78 | } |
79 | } |
80 | |
81 | private static class LinkedList { |
82 | Node head; |
83 | Node tail; |
84 | Node last; |
85 | |
86 | LinkedList() { |
87 | head = new Node(0, 0); |
88 | tail = new Node(0, -1); |
89 | last = head; |
90 | } |
91 | |
92 | void addElement(Node node) { |
93 | node.next = tail; |
94 | last.next = node; |
95 | last = last.next; |
96 | } |
97 | |
98 | void addElement(int coefficient, int exponent) { |
99 | addElement(new Node(coefficient, exponent)); |
100 | } |
101 | } |
102 | |
103 | private static class InputReader { |
104 | BufferedReader reader; |
105 | StringTokenizer tokenizer; |
106 | |
107 | InputReader(InputStream stream) { |
108 | reader = new BufferedReader(new InputStreamReader(stream), 32768); |
109 | tokenizer = null; |
110 | } |
111 | |
112 | String next() { |
113 | while (tokenizer == null || !tokenizer.hasMoreTokens()) { |
114 | try { |
115 | tokenizer = new StringTokenizer(reader.readLine()); |
116 | } catch (IOException e) { |
117 | throw new RuntimeException(e); |
118 | } |
119 | } |
120 | return tokenizer.nextToken(); |
121 | } |
122 | |
123 | public int nextInt() { |
124 | return Integer.parseInt(next()); |
125 | } |
126 | } |
127 | } |
128 | |
129 | /************************************************************** |
130 | Problem: 1261 |
131 | User: |
132 | Language: Java |
133 | Result: Accepted |
134 | Time:1948 ms |
135 | Memory:126244 kb |
136 | ****************************************************************/ |
Problem B: Black era
Description
The war in Ursus has broken out! Now, Wamiya and her teammates have to escape from this dangerous place immediately. In order to avoid the falling objects from the surrounding buildings, all the team members are lined up in a row while moving forward. In order to defend against enemy attacks, Wamiya should also constantly change the form of the team by exchanging two parts of the row, i.e., she will specify two continuous parts in the row, and exchange their locations without changing anything inside each part. There will be $N$ members in the team, and Wamiya will give $M$ orders one by one. Given the initial team, what will be the final team after their escape?
Input
First line contains one integer $T$, indicating that there will be $T$ cases.
For each case, the first line will be two integers $N$ and $M$. $N$ is the number of the members in the team, and $M$ is the number of orders.
The second line will be $N$ integers, indicating the initial formation of the team. Each number is unique and represents the ID of the member. We guarantee that ID is in the range of $[0,N−1]$.
The following $M$ lines represent $M$ orders. In each line, there are four integers $x_1,y_1,x_2,y_2$, which mean the part $[x_1,y_1]$ (starting from member with ID $x_1$ and ending at the member with ID $y_1$), should exchange the position with part $[x_2,y_2]$.
$T≤5,1≤N,M≤10^5$. We guarantee that in each order, members with ID $x_1,y_1,x_2,y_2$ will be arranged in order from front to back in the row. Notice that $x_1$ could be equal to $y_1$ and $x_2$ could be equal to $y_2$.
Output
For each case, output $N$ integer in one line to represent the final team consisting of member IDs.
Sample Input
1 | 1 |
2 | 10 2 |
3 | 0 6 5 1 2 3 4 8 7 9 |
4 | 6 4 7 9 |
5 | 0 8 6 5 |
Sample Output
1 | 6 5 0 7 9 8 1 2 3 4 |
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | struct Node { |
7 | int id; |
8 | Node* previous; |
9 | Node* next; |
10 | Node(int id) { |
11 | this->id = id; |
12 | previous = NULL; |
13 | next = NULL; |
14 | } |
15 | }; |
16 | |
17 | class linkedList { |
18 | public: |
19 | Node* head; |
20 | Node* tail; |
21 | |
22 | linkedList() { |
23 | head = new Node(-2); |
24 | tail = new Node(-1); |
25 | head->next = tail; |
26 | tail->previous = head; |
27 | } |
28 | |
29 | void addElement(Node* node) { |
30 | node->previous = tail->previous; |
31 | node->next = tail; |
32 | tail->previous->next = node; |
33 | tail->previous = node; |
34 | } |
35 | |
36 | void exchange(Node* x1, Node* y1, Node* x2, Node* y2) { |
37 | Node* temp = x1->previous; |
38 | temp->next = x2; |
39 | x2->previous->next = x1; |
40 | x1->previous = x2->previous; |
41 | x2->previous = temp; |
42 | temp = y2->next; |
43 | temp->previous = y1; |
44 | y1->next->previous = y2; |
45 | y2->next = y1->next; |
46 | y1->next = temp; |
47 | } |
48 | |
49 | void print() { |
50 | for (Node* i = head->next; i->id > -1; i = i->next) printf("%d ", i->id); |
51 | printf("\n"); |
52 | } |
53 | |
54 | void destory() { |
55 | Node* current = head; |
56 | while (current != NULL) { |
57 | Node* temp = current->next; |
58 | delete current; |
59 | current = temp; |
60 | } |
61 | } |
62 | }; |
63 | |
64 | int readInt(); |
65 | Node* address[100000]; |
66 | |
67 | int main() { |
68 | int testCase = readInt(); |
69 | while (testCase--) { |
70 | int members = readInt(); |
71 | int reorders = readInt(); |
72 | linkedList team = linkedList(); |
73 | while (members--) { |
74 | int id = readInt(); |
75 | address[id] = new Node(id); |
76 | team.addElement(address[id]); |
77 | } |
78 | while (reorders--) { |
79 | int x1 = readInt(), y1 = readInt(), x2 = readInt(), y2 = readInt(); |
80 | team.exchange(address[x1], address[y1], address[x2], address[y2]); |
81 | } |
82 | team.print(); |
83 | team.destory(); |
84 | } |
85 | return 0; |
86 | } |
87 | |
88 | |
89 | int readInt() { |
90 | char r; |
91 | bool start = false, neg = false; |
92 | int ret = 0; |
93 | while (true) { |
94 | r = getchar(); |
95 | if ((r - '0' < 0 || r - '0' > 9) && r != '-' && !start) continue; |
96 | if ((r - '0' < 0 || r - '0' > 9) && r != '-' && start) break; |
97 | if (start) ret *= 10; |
98 | start = true; |
99 | if (r == '-')neg = true; |
100 | else ret += r - '0'; |
101 | } |
102 | if (!neg) |
103 | return ret; |
104 | else |
105 | return -ret; |
106 | } |
107 | |
108 | /************************************************************** |
109 | Problem: 1262 |
110 | User: |
111 | Language: C++ |
112 | Result: Accepted |
113 | Time:128 ms |
114 | Memory:5036 kb |
115 | ****************************************************************/ |
Problem C: Converted Vinux input
Description
Narnal is a huge fan of vim, so he has created a text editor called Vinux, which can only edit one line with several operations. Each line has an invisible undeletable tail character called EOL (end of line), which will always stay at the end of the line in any circumstance. Notice that the undeletable property of EOL means that EOL will revive immediately at the end of the line whenever it vanishes (been replaced or deleted). He wants to covert a one-line keyboard input containing operations and digits into a one-line real input with only digits.
Only the following operations are available:
r: next single input would replace the current character;
I: move the character pointer to the head of the line;
H: left shift the current character pointer unless it is at the leftmost place;
L: right shift the current character pointer unless it is at the rightmost place;
x: delete the current character;
Otherwise, each input would insert before the current character.
Input
First line will be a positive integer $T$, which is the number of test cases.
In each test case, the first line would be an integer $n$ for the length of the keyboard input of Vinux. Then the following line represents the keyboard input of Vinux.
$T≤20,20≤n≤10^5$. The aiming real input only contains digits without blanks. The input would always be valid (the input after r would never be an operation character).
Output
For each case, output one line shows the real input without EOL.
Sample Input
1 | 2 |
2 | 25 |
3 | 12345HHHr9Ir000LLLLL876Ix |
4 | 20 |
5 | r60xxxxHx4xHH3III1I2 |
Sample Output
1 | 002945876 |
2 | 2134 |
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | struct Node { |
7 | char character; |
8 | Node* previous; |
9 | Node* next; |
10 | Node(char character) { |
11 | this->character = character; |
12 | previous = NULL; |
13 | next = NULL; |
14 | } |
15 | }; |
16 | |
17 | class linkedList { |
18 | public: |
19 | Node* head; |
20 | Node* tail; |
21 | Node* current; |
22 | |
23 | linkedList() { |
24 | head = new Node(' '); |
25 | tail = new Node('\n'); |
26 | head->next = tail; |
27 | tail->previous = head; |
28 | current = tail; |
29 | } |
30 | |
31 | void addElement(Node* node) { |
32 | node->previous = current->previous; |
33 | node->next = current; |
34 | current->previous->next = node; |
35 | current->previous = node; |
36 | } |
37 | |
38 | void addElement(char c) { |
39 | addElement(new Node(c)); |
40 | } |
41 | |
42 | void print() { |
43 | for (Node* i = head->next; i != NULL; i = i->next) putchar(i->character); |
44 | } |
45 | |
46 | void destory() { |
47 | current = head; |
48 | while (current != NULL) { |
49 | Node* temp = current->next; |
50 | delete current; |
51 | current = temp; |
52 | } |
53 | } |
54 | |
55 | void del(Node* node) { |
56 | node->previous->next = node->next; |
57 | node->next->previous = node->previous; |
58 | delete(node); |
59 | } |
60 | }; |
61 | |
62 | int readInt(); |
63 | bool isDigit(char c); |
64 | |
65 | int main() { |
66 | int testCase = readInt(); |
67 | while (testCase--) { |
68 | int input = readInt(); |
69 | linkedList str = linkedList(); |
70 | while (input--) { |
71 | char c = getchar(); |
72 | if (isDigit(c)) str.addElement(c); |
73 | else { |
74 | switch (c) { |
75 | case 'r': { |
76 | if (input == 0) break; |
77 | c = getchar(); |
78 | input--; |
79 | if (str.current->character == '\n') { |
80 | str.addElement('\n'); |
81 | str.current = str.current->previous; |
82 | } |
83 | str.current->character = c; |
84 | break; |
85 | } |
86 | case 'I': { |
87 | str.current = str.head->next; |
88 | break; |
89 | } |
90 | case 'H': { |
91 | if (str.current->previous->character == ' ') break; |
92 | str.current = str.current->previous; |
93 | break; |
94 | } |
95 | case 'L': { |
96 | if (str.current->character == '\n') break; |
97 | str.current = str.current->next; |
98 | break; |
99 | } |
100 | case 'x': { |
101 | if (str.current->character == '\n') break; |
102 | str.current = str.current->next; |
103 | str.del(str.current->previous); |
104 | } |
105 | } |
106 | } |
107 | } |
108 | str.print(); |
109 | str.destory(); |
110 | } |
111 | return 0; |
112 | } |
113 | |
114 | bool isDigit(char c) { |
115 | return '0' <= c && c <= '9'; |
116 | } |
117 | |
118 | int readInt() { |
119 | char r; |
120 | bool start = false, neg = false; |
121 | int ret = 0; |
122 | while (true) { |
123 | r = getchar(); |
124 | if ((r - '0' < 0 || r - '0' > 9) && r != '-' && !start) continue; |
125 | if ((r - '0' < 0 || r - '0' > 9) && r != '-' && start) break; |
126 | if (start) ret *= 10; |
127 | start = true; |
128 | if (r == '-') neg = true; |
129 | else ret += r - '0'; |
130 | } |
131 | if (!neg) return ret; |
132 | else return -ret; |
133 | } |
134 | |
135 | /************************************************************** |
136 | Problem: 1263 |
137 | User: |
138 | Language: C++ |
139 | Result: Accepted |
140 | Time:144 ms |
141 | Memory:3856 kb |
142 | ****************************************************************/ |
Problem D: Difficult Josephus problem
Description
Josephus problem is a theoretical problem related to a certain counting-out game. However, Narnal thought this problem is too easy for him, so he constructed a more complex Josephus problem as following.
There are nn people standing in a circle indexing from $1$ to $n$, and each person in the circle holds a note marked with a positive integer. At first, given a positive integer mm, people count the number from one to the next starting from index $1$ in clockwise ($1,2,…,n,1,2,…$). When the counted number reaches $m$, the corresponding person will be eliminated from the circle and yell the number in his/her note, denoted by $k_i$, and then people restart counting from the next person targeting for number $k_i$ until, eventually, only one person is left in the circle.
Input
First line will be a positive integer $T$, which is the number of test cases.
In each test case, the first line would be two integers $n$ and $m$, where $n$ is the initial number of people, and $m$ is the initial target counting number.
Then there will be a single line containing $n$ integers, indicating the number on each person’s note, from index $1$ to index $n$.
$T≤100,1≤n≤10^4$. $m$ and each number on the notes will be in the range of $[1,108]$. We guarantee that there are no more than $20$ cases with $n>5×10^3$.
Output
For each case, output one line with one integer for the index of the remaining people.
Sample Input
1 | 2 |
2 | 5 2 |
3 | 2 2 2 2 2 |
4 | 10 10 |
5 | 100000000 1 2 3 4 5 6 7 8 9 |
Sample Output
1 | 3 |
2 | 1 |
Code
1 |
|
2 | |
3 | using namespace std; |
4 | |
5 | struct Node { |
6 | int id; |
7 | int count; |
8 | Node* previous; |
9 | Node* next; |
10 | Node(int id, int count) { |
11 | this->id = id; |
12 | this->count = count; |
13 | previous = NULL; |
14 | next = NULL; |
15 | } |
16 | }; |
17 | |
18 | class linkedList { |
19 | public: |
20 | Node* head, * tail; |
21 | int length; |
22 | |
23 | linkedList(int id, int count) { |
24 | length = 1; |
25 | head = new Node(id, count); |
26 | tail = head; |
27 | } |
28 | |
29 | void addElement(Node* node) { |
30 | length++; |
31 | tail->next = node; |
32 | node->previous = tail; |
33 | tail = node; |
34 | } |
35 | |
36 | void addElement(int id, int count) { |
37 | addElement(new Node(id, count)); |
38 | } |
39 | |
40 | void del(Node* node) { |
41 | if (node == head) head = head->previous; |
42 | node->previous->next = node->next; |
43 | node->next->previous = node->previous; |
44 | delete(node); |
45 | length--; |
46 | } |
47 | |
48 | void loop() { |
49 | if (length == 1) return; |
50 | head->previous = tail; |
51 | tail->next = head; |
52 | } |
53 | }; |
54 | |
55 | int readInt(); |
56 | |
57 | int main() { |
58 | int testCase = readInt(); |
59 | while (testCase--) { |
60 | int members = readInt(); |
61 | int loop = readInt(); |
62 | linkedList circle = linkedList(1, readInt()); |
63 | for (int i = 2; i <= members; i++) circle.addElement(i, readInt()); |
64 | circle.loop(); |
65 | Node* start = circle.head; |
66 | while (circle.length != 1) { |
67 | loop %= circle.length; |
68 | Node* temp = start; |
69 | if (circle.length - loop >= circle.length >> 1) { |
70 | while (loop--) temp = temp->next; |
71 | start = temp; |
72 | loop = temp->previous->count; |
73 | circle.del(temp->previous); |
74 | } |
75 | else { |
76 | loop = circle.length - loop; |
77 | while (loop--) temp = temp->previous; |
78 | start = temp; |
79 | loop = temp->previous->count; |
80 | circle.del(temp->previous); |
81 | } |
82 | } |
83 | printf("%d\n", circle.head->id); |
84 | } |
85 | return 0; |
86 | } |
87 | |
88 | int readInt() { |
89 | char r; |
90 | bool start = false, neg = false; |
91 | int ret = 0; |
92 | while (true) { |
93 | r = getchar(); |
94 | if ((r - '0' < 0 || r - '0' > 9) && r != '-' && !start) continue; |
95 | if ((r - '0' < 0 || r - '0' > 9) && r != '-' && start) break; |
96 | if (start) ret *= 10; |
97 | start = true; |
98 | if (r == '-') neg = true; |
99 | else ret += r - '0'; |
100 | } |
101 | if (!neg) return ret; |
102 | else return -ret; |
103 | } |
104 | |
105 | /************************************************************** |
106 | Problem: 1264 |
107 | User: |
108 | Language: C++ |
109 | Result: Accepted |
110 | Time:1240 ms |
111 | Memory:1480 kb |
112 | ****************************************************************/ |
Problem E: Eccentric calculator
Description
Yuki is a clever girl and she is playing an eccentric calculator. The eccentric calculator can only display $n$ digits, which really annoys her.
She enters a number $m$ in the calculator first, and then just repeatedly squares it until the result overflows. When it overflows, only the $n$ most significant digits can still be displayed on the screen, and an error will appear at the same time. Yuki can clear the error flag and continue squaring the displayed number. She wonders what is the largest number she can get by repeatedly doing this procedure for given $n$ and $m$.
Input
The first line contains an integer $t$ ($1≤t≤200$) — the number of test cases. Each test case contains one line with two integers: $n$ and $m$ ($1≤n≤9,0≤m<10^n$) — the number of digits and the starting number.
Output
For each test case, print one line with the maximum number that Yuki can obtain.
Sample Input
1 | 2 |
2 | 1 5 |
3 | 2 99 |
Sample Output
1 | 5 |
2 | 99 |
HINT
Yuki can obtain $5→2(5)→4→1(6)→1→1→⋯$ respectively in the first case by repeatedly squaring it.
Code
1 |
|
2 | |
3 | using namespace std; |
4 | |
5 | int readInt(); |
6 | int generateNext(int number, int maxLen); |
7 | |
8 | int max; |
9 | |
10 | int main() { |
11 | auto testCase = readInt(); |
12 | while (testCase--) { |
13 | auto digit = readInt(); |
14 | auto number = readInt(); |
15 | if (number == 0) { |
16 | printf("%d\n", number); |
17 | continue; |
18 | } |
19 | int maxLen = 1; |
20 | while (digit--) maxLen *= 10; |
21 | max = number; |
22 | auto slow = generateNext(number, maxLen); |
23 | auto fast = generateNext(slow, maxLen); |
24 | while (slow != fast) { |
25 | slow = generateNext(slow, maxLen); |
26 | fast = generateNext(generateNext(fast, maxLen), maxLen); |
27 | } |
28 | printf("%d\n", max); |
29 | } |
30 | return 0; |
31 | } |
32 | |
33 | int readInt() { |
34 | char r; |
35 | bool start = false, neg = false; |
36 | int ret = 0; |
37 | while (true) { |
38 | r = getchar(); |
39 | if ((r - '0' < 0 || r - '0' > 9) && r != '-' && !start) continue; |
40 | if ((r - '0' < 0 || r - '0' > 9) && r != '-' && start) break; |
41 | if (start) ret *= 10; |
42 | start = true; |
43 | if (r == '-') neg = true; |
44 | else ret += r - '0'; |
45 | } |
46 | if (!neg) return ret; |
47 | else return -ret; |
48 | } |
49 | |
50 | int generateNext(int number, int maxLen) { |
51 | auto temp = (long long)number * (long long)number; |
52 | while (temp / maxLen != 0) temp /= 10; |
53 | if (temp > max) max = (int)temp; |
54 | return (int)temp; |
55 | } |
56 | /************************************************************** |
57 | Problem: 1265 |
58 | User: |
59 | Language: C++ |
60 | Result: Accepted |
61 | Time:1632 ms |
62 | Memory:1092 kb |
63 | ****************************************************************/ |
1 |
|
2 | |
3 | int generateNext(int number, int maxLen); |
4 | |
5 | int max; |
6 | |
7 | int main() { |
8 | int testCase; |
9 | scanf("%d", &testCase); |
10 | while (testCase--) { |
11 | int digit, number; |
12 | scanf("%d %d", &digit, &number); |
13 | if (number == 0) { |
14 | printf("%d\n", number); |
15 | continue; |
16 | } |
17 | int maxLen = 1; |
18 | while (digit--) maxLen *= 10; |
19 | max = number; |
20 | int slow = generateNext(number, maxLen); |
21 | int fast = generateNext(slow, maxLen); |
22 | while (slow != fast) { |
23 | slow = generateNext(slow, maxLen); |
24 | fast = generateNext(generateNext(fast, maxLen), maxLen); |
25 | } |
26 | printf("%d\n", max); |
27 | } |
28 | return 0; |
29 | } |
30 | |
31 | int generateNext(int number, int maxLen) { |
32 | long long temp = (long long)number * (long long)number; |
33 | while (temp / maxLen != 0) temp /= 10; |
34 | if (temp > max) max = (int)temp; |
35 | return (int)temp; |
36 | } |
37 | /************************************************************** |
38 | Problem: 1265 |
39 | User: |
40 | Language: C |
41 | Result: Accepted |
42 | Time:1644 ms |
43 | Memory:1092 kb |
44 | ****************************************************************/ |
1 | import java.io.BufferedReader; |
2 | import java.io.IOException; |
3 | import java.io.InputStream; |
4 | import java.io.InputStreamReader; |
5 | import java.util.StringTokenizer; |
6 | |
7 | public class Main { |
8 | private static int max; |
9 | public static void main(String[] args) { |
10 | InputReader input = new InputReader(System.in); |
11 | int testCase = input.nextInt(); |
12 | while (testCase-- > 0) { |
13 | int digit = input.nextInt(); |
14 | int number = input.nextInt(); |
15 | if (number == 0) { |
16 | System.out.printf("%d\n", number); |
17 | continue; |
18 | } |
19 | int maxLen = 1; |
20 | while (digit-->0) maxLen *= 10; |
21 | max = number; |
22 | int slow = generateNext(number, maxLen); |
23 | int fast = generateNext(slow, maxLen); |
24 | while (slow != fast) { |
25 | slow = generateNext(slow, maxLen); |
26 | fast = generateNext(generateNext(fast, maxLen), maxLen); |
27 | } |
28 | System.out.printf("%d\n", max); |
29 | } |
30 | } |
31 | |
32 | private static class InputReader { |
33 | BufferedReader reader; |
34 | StringTokenizer tokenizer; |
35 | |
36 | InputReader(InputStream stream) { |
37 | reader = new BufferedReader(new InputStreamReader(stream), 32768); |
38 | tokenizer = null; |
39 | } |
40 | |
41 | String next() { |
42 | while (tokenizer == null || !tokenizer.hasMoreTokens()) { |
43 | try { |
44 | tokenizer = new StringTokenizer(reader.readLine()); |
45 | } catch (IOException e) { |
46 | throw new RuntimeException(e); |
47 | } |
48 | } |
49 | return tokenizer.nextToken(); |
50 | } |
51 | |
52 | int nextInt() { |
53 | return Integer.parseInt(next()); |
54 | } |
55 | } |
56 | |
57 | private static int generateNext(int number, int maxLen) { |
58 | long temp = (long)number * (long)number; |
59 | while (temp / maxLen != 0) temp /= 10; |
60 | if (temp > max) max = (int)temp; |
61 | return (int)temp; |
62 | } |
63 | } |
64 | |
65 | /************************************************************** |
66 | Problem: 1265 |
67 | User: |
68 | Language: Java |
69 | Result: Accepted |
70 | Time:1820 ms |
71 | Memory:19344 kb |
72 | ****************************************************************/ |
Problem F: From-now-on minimum difference
Description
Yuki is a clever girl and she is good at mathematics. One day, she gets an array $a$ of $n$ integers: $a_1,a_2,…,a_n$. She wants to know the from-now-on minimum difference of $a_1,a_2,…,a_{n−1}$, and your task is to help her to calculate them. The from-now-on minimum difference of $a_i$, denoted by $h_i$, is defined as: $h_i=min_{j>i}|a_j−a_i|$.
Input
The first line contains one integer: $n$ ($2≤n≤2×10^6$). The second line contains $n$ space-separated integers: $a_1,a_2,…,a_n$ — elements of the array $a$ ($1≤a_i≤10^9$ ).
Output
Print one line with $n−1$ space-separated intergers: $h_1,h_2,…,h_{n−1}$.
Sample Input
1 | 5 |
2 | 1 2 3 4 5 |
Sample Output
1 | 1 1 1 1 |
HINT
You may solve this problem using some advanced data structures. However, it can be solved in a simple and efficient way merely by sorting algorithm\ and linked list\.
Please note that the size of input might be really large, so you might want to use an efficient way to read the input data.
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | struct Node { |
7 | int number; |
8 | Node* next; |
9 | Node* previous; |
10 | Node* exNext; |
11 | Node* exPrevious; |
12 | Node(int number) { |
13 | this->number = number; |
14 | this->next= this->previous = this->exNext = this->exPrevious = NULL; |
15 | } |
16 | }; |
17 | |
18 | class linkedList { |
19 | public: |
20 | Node* head, * tail, * current; |
21 | linkedList() { |
22 | this->current = this->head = new Node(-1); |
23 | this->tail = new Node(0); |
24 | this->head->next = tail; |
25 | this->tail->previous = head; |
26 | } |
27 | |
28 | void addNode(Node* node) { |
29 | node->next = this->current->next; |
30 | node->previous = this->current; |
31 | this->current->next->previous = node; |
32 | this->current->next = node; |
33 | this->current = node; |
34 | } |
35 | }; |
36 | |
37 | class pairedLinkedList { |
38 | public: |
39 | Node* head, * tail, * current; |
40 | pairedLinkedList() { |
41 | this->current = this->head = new Node(-1); |
42 | this->tail = new Node(0); |
43 | this->head->exNext = tail; |
44 | this->tail->exPrevious = head; |
45 | } |
46 | |
47 | pairedLinkedList(Node* head, Node* tail) { |
48 | this->current = this->head = head; |
49 | this->tail = tail; |
50 | head->exNext = tail; |
51 | tail->exPrevious = head; |
52 | } |
53 | |
54 | void addNode(Node* node) { |
55 | node->exNext = this->current->exNext; |
56 | node->exPrevious = this->current; |
57 | this->current->exNext->exPrevious = node; |
58 | this->current->exNext = node; |
59 | this->current = node; |
60 | } |
61 | }; |
62 | |
63 | int readInt(); |
64 | bool compare(Node* n1, Node* n2); |
65 | |
66 | Node* index[2000000]; |
67 | |
68 | int main() { |
69 | int len = readInt(); |
70 | linkedList rigion = linkedList(); |
71 | for (int i = 0; i < len; i++) { |
72 | index[i] = new Node(readInt()); |
73 | rigion.addNode(index[i]); |
74 | } |
75 | std::sort(index, index + len, compare); |
76 | pairedLinkedList sortedL = pairedLinkedList(rigion.head, rigion.tail); |
77 | for (int i = 0; i < len; i++) sortedL.addNode(index[i]); |
78 | for (Node* i = rigion.head->next, *temp; i->next->next!=NULL; i = temp) { |
79 | temp = i->next; |
80 | if (i->exPrevious == sortedL.head) printf("%d ", i->exNext->number - i->number); |
81 | else if (i->exNext == sortedL.tail) printf("%d ", i->number - i->exPrevious->number); |
82 | else if (i->number - i->exPrevious->number > i->exNext->number - i->number) printf("%d ", i->exNext->number - i->number); |
83 | else printf("%d ", i->number - i->exPrevious->number); |
84 | i->next->previous = i->previous; |
85 | i->previous->next = i->next; |
86 | i->exNext->exPrevious = i->exPrevious; |
87 | i->exPrevious->exNext = i->exNext; |
88 | delete(i); |
89 | } |
90 | return 0; |
91 | } |
92 | |
93 | int readInt() { |
94 | int num = 0; |
95 | char l = getchar(); |
96 | bool sign = false, negative = false; |
97 | switch (l) { |
98 | case '-': negative = true; |
99 | case '+': sign = true; |
100 | } |
101 | if (sign) l = getchar(); |
102 | while ('0' <= l && l <= '9') { |
103 | num = num * 10 + l - '0'; |
104 | l = getchar(); |
105 | } |
106 | if (negative) return -num; |
107 | return num; |
108 | } |
109 | |
110 | bool compare(Node* n1, Node* n2) { |
111 | return n1->number < n2->number; |
112 | } |
113 | /************************************************************** |
114 | Problem: 1266 |
115 | User: |
116 | Language: C++ |
117 | Result: Accepted |
118 | Time:1360 ms |
119 | Memory:110568 kb |
120 | ****************************************************************/ |
Problem G: Gnisrever
Description
Narnal loves reversing and Fibonacci sequence. When he gets an array with length $N$, he would reverse the array in the intervals determined by Fibonacci sequence for $K$ times.
Let $F_n$ is the $n$-th Fibonacci number: $F_1=F_2=1,F_n=F_{n−1}+F_{n−2}$ for all $n≥3$.
Let $s_n=F_{2n−1} mod N$ and let $t_n=F_{2n} mod N$.
Narnal’s reversing always starts with an array of integers $A=(A[0],…,A[N−1])$ where initially every $A[i]$ is equal to $i$. Now perform $K$ successive operations on $A$, where the $j$-th operation consists of reversing the order of those elements in $A$ with indices between $s_j$ and $t_j$ (both ends inclusive).
Finally, Narnal’s happiness is defined as $R(N,K)=\sum_{i=0}^{N-1}i*A[i]$ after $K$ operations.
$1≤N≤10^{15},1≤K≤5×10^3$.
Input
One line gives $N$ and $K$, separated by space.
Output
One line with only $R(N,K) mod 10^6$.
Sample Input
1 | 5 4 |
Sample Output
1 | 27 |
HINT
Consider using nodes to represent the sequences of consecutive numbers.
Using linked list reversing!
$R(5,4)=27$ can be seen from the following procedure:
Initial position: $(0,1,2,3,4)$
Step 1 - Reverse $A[1]$ to $A[1]$: $(0,1,2,3,4)$
Step 2 - Reverse $A[2]$ to $A[3]$: $(0,1,3,2,4)$
Step 3 - Reverse $A[0]$ to $A[3]$: $(2,3,1,0,4)$
Step 4 - Reverse $A[3]$ to$A[1]$: $(2,0,1,3,4)$
$R(5,4)=0×2+1×0+2×1+3×3+4×4=27$.
Also, $R(10^2,10^2)=246597$.
Lab4_Stack_and_Queue
Problem A: Magic Queue
Description
IceRuler likes Queues. So he gives you an empty queue initially and some operations on this queue.
The operations contains:
- E x Enqueue x
- D Dequeue
- A Print the head of the queue.
Finally, You should output all elements in the queue after all operations.
Input
There is only one testcase. The first line is integer n, the number of operations. ($1 \leq n \leq 20000000$) Then n lines for these operations, x in int range.
Output
Do each operation, if it is type ‘A’, print current queue head in one line. After doing all operations, output the final queue elements in one line, if the queue is empty, print nothing. It is guaranteed that all operations are legal.
Sample Input
1 | 7 |
2 | E 1 |
3 | E 2 |
4 | E 3 |
5 | A |
6 | D |
7 | E 1 |
8 | A |
Sample Output
1 | 1 |
2 | 2 |
3 | 2 3 1 |
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | struct Node { |
7 | int number; |
8 | Node* next; |
9 | Node* previous; |
10 | Node(int number) { |
11 | this->number = number; |
12 | this->next = this->previous = NULL; |
13 | } |
14 | }; |
15 | |
16 | class Queue { |
17 | private: |
18 | Node* head, * tail; |
19 | void addNode(Node* node) { |
20 | node->next = this->tail; |
21 | node->previous = this->tail->previous; |
22 | node->next->previous = node; |
23 | node->previous->next = node; |
24 | } |
25 | |
26 | void deleteNode(Node* node) { |
27 | node->next->previous = node->previous; |
28 | node->previous->next = node->next; |
29 | delete(node); |
30 | } |
31 | |
32 | public: |
33 | Queue() { |
34 | this->head = new Node(-1); |
35 | this->tail = new Node(0); |
36 | this->head->next = tail; |
37 | this->tail->previous = head; |
38 | } |
39 | |
40 | void enQueue(int n) { this->addNode(new Node(n)); } |
41 | |
42 | int deQueue() { |
43 | int ret = this->head->next->number; |
44 | this->deleteNode(this->head->next); |
45 | return ret; |
46 | } |
47 | |
48 | int getHead() { return this->head->next->number; } |
49 | |
50 | void print() { |
51 | for (Node* i = this->head->next; i->next != NULL; i = i->next) printf("%d ", i->number); |
52 | printf("\n"); |
53 | } |
54 | }; |
55 | |
56 | int main() { |
57 | int testCase; |
58 | scanf("%d", &testCase); |
59 | Queue queue = Queue(); |
60 | while (testCase--) { |
61 | char c[2]; |
62 | scanf("%s", &c); |
63 | switch (c[0]) { |
64 | case 'E': { |
65 | int i; |
66 | scanf("%d", &i); |
67 | queue.enQueue(i); |
68 | break; |
69 | } |
70 | case 'D': { |
71 | queue.deQueue(); |
72 | break; |
73 | } |
74 | case 'A': printf("%d\n", queue.getHead()); |
75 | } |
76 | } |
77 | queue.print(); |
78 | return 0; |
79 | } |
80 | |
81 | /************************************************************** |
82 | Problem: 1269 |
83 | User: |
84 | Language: C++ |
85 | Result: Accepted |
86 | Time:504 ms |
87 | Memory:1216 kb |
88 | ****************************************************************/ |
Problem B: Magic brackets
Description
IceRuler likes Brackets. He has n brackets sequences. And you should tell him whether they are matched. The brackets will only contain {, }, (, ), [, ]. The matching rules are the same as in Math.
Input
The first line is integer $T$, the number of test cases ($1 \leq T \leq 20$). For each test case, there is an integer n in one line($1 \leq n \leq 30000$) and $n$ lines means $n$ brackets sequences.
Output
For each brackets sequences, print “YES” if it is matched. Otherwise, print “NO”.
Sample Input
1 | 7 |
2 | 1 |
3 | ( |
4 | 2 |
5 | () |
6 | 2 |
7 | {] |
8 | 6 |
9 | [(){}] |
10 | 4 |
11 | (])[ |
12 | 8 |
13 | [[{{}}]] |
14 | 6 |
15 | [][{]] |
Sample Output
1 | NO |
2 | YES |
3 | NO |
4 | YES |
5 | NO |
6 | YES |
7 | NO |
HINT
Origin pro.
Code
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | char getBracket(); |
8 | char getPair(char c); |
9 | |
10 | int main() { |
11 | int testCase; |
12 | scanf("%d", &testCase); |
13 | while (testCase--) { |
14 | int len; |
15 | scanf("%d", &len); |
16 | char c; |
17 | if (len == 1) { |
18 | c = getBracket(); |
19 | printf("NO\n"); |
20 | continue; |
21 | } |
22 | std::stack<char> brackets; |
23 | bool hasRight = false; |
24 | while (len--) { |
25 | c = getBracket(); |
26 | switch (c) { |
27 | case ')': |
28 | case ']': |
29 | case '}': { |
30 | if (brackets.empty()) { |
31 | hasRight = true; |
32 | break; |
33 | } |
34 | if (getPair(c) == brackets.top()) brackets.pop(); |
35 | else hasRight = true; |
36 | break; |
37 | } |
38 | case '(': |
39 | case '[': |
40 | case '{': brackets.push(c); |
41 | } |
42 | } |
43 | if(!hasRight && brackets.empty()) printf("YES\n"); |
44 | else printf("NO\n"); |
45 | } |
46 | return 0; |
47 | } |
48 | |
49 | bool isBracket(char c) { |
50 | return c == '(' || c == '[' || c == '{' || c == ')' || c == ']' || c == '}'; |
51 | } |
52 | |
53 | char getBracket() { |
54 | char c = getchar(); |
55 | while (!isBracket(c)) c = getchar(); |
56 | return c; |
57 | } |
58 | |
59 | char getPair(char c) { |
60 | switch (c) { |
61 | case '(': return ')'; |
62 | case ')': return '('; |
63 | case '[': return ']'; |
64 | case ']': return '['; |
65 | case '{': return '}'; |
66 | case '}': return '{'; |
67 | default: return ' '; |
68 | } |
69 | } |
70 | /************************************************************** |
71 | Problem: 1214 |
72 | User: |
73 | Language: C++ |
74 | Result: Accepted |
75 | Time:0 ms |
76 | Memory:1252 kb |
77 | ****************************************************************/ |
Problem C: Magic Sequences
Description
IceRuler has a sequence $A = [a_1,a_2,…,a_n]$. With a magic number m, he wants you to tell him the maximum element in these intervals $[a_1,..a_m], [a_2,…a_{m+1}],…[a_{n-m+1},…,a_n]$.
Input
The first line is the magic number m. The second line contains n integers, where the $i$th integer represents the integer ai. Input ends with a number -1. Constraints: $1 ≤ m < n$ $1 ≤ n ≤ 2000000$ $0 ≤ a_i ≤ 1000000000$
Output
Print one integer K in one line, represents the XOR sum of the maximum elements in $a[i]..a[i +m-1]$s. $K = the max number in [a1,..am] ⊕ the max number in [a2,..am+1] …….⊕ the max number in [an-m+1,..an]$. ⊕ is the bit operation exclusive OR.
Sample Input
1 | 5 |
2 | 121 123 122 13 12 12 52 2 6 7 32 7 324 34 124 213 214 1412 -1 |
Sample Output
1 | 1178 |
HINT
Easy pro.
Code
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | int main() { |
8 | int size; |
9 | scanf("%d", &size); |
10 | int XORsum = 0; |
11 | deque<int> window; |
12 | deque<int> INDEX; |
13 | int index = 0; |
14 | int t; |
15 | scanf("%d", &t); |
16 | for (; index < size; index++) { |
17 | while (!window.empty() && t > window.back()) { |
18 | window.pop_back(); |
19 | INDEX.pop_back(); |
20 | } |
21 | window.push_back(t); |
22 | INDEX.push_back(index); |
23 | scanf("%d", &t); |
24 | } |
25 | XORsum ^= window.front(); |
26 | while (t != -1) { |
27 | while (!window.empty() && t > window.back()) { |
28 | window.pop_back(); |
29 | INDEX.pop_back(); |
30 | } |
31 | if (!INDEX.empty() && INDEX.front() <= index - size) { |
32 | INDEX.pop_front(); |
33 | window.pop_front(); |
34 | } |
35 | window.push_back(t); |
36 | INDEX.push_back(index); |
37 | XORsum ^= window.front(); |
38 | scanf("%d", &t); |
39 | index++; |
40 | } |
41 | printf("%d\n", XORsum); |
42 | return 0; |
43 | } |
44 | |
45 | /************************************************************** |
46 | Problem: 1215 |
47 | User: |
48 | Language: C++ |
49 | Result: Accepted |
50 | Time:324 ms |
51 | Memory:1252 kb |
52 | ****************************************************************/ |
1 | import java.util.Deque; |
2 | import java.util.LinkedList; |
3 | import java.util.Scanner; |
4 | |
5 | public class Main { |
6 | public static void main(String[] args) { |
7 | Scanner input = new Scanner(System.in); |
8 | Deque<Integer> window = new LinkedList<>(); |
9 | Deque<Integer> indexs = new LinkedList<>(); |
10 | int size = input.nextInt(); |
11 | int n = input.nextInt(); |
12 | int index = 0; |
13 | int XORsum = 0; |
14 | for (; index < size; index++) { |
15 | while(!window.isEmpty() && n > window.getLast()) { |
16 | window.pollLast(); |
17 | indexs.pollLast(); |
18 | } |
19 | window.addLast(n); |
20 | indexs.addLast(index); |
21 | n = input.nextInt(); |
22 | } |
23 | XORsum ^= window.getFirst(); |
24 | while(n != -1) { |
25 | while(!window.isEmpty() && n > window.getLast()) { |
26 | window.pollLast(); |
27 | indexs.pollLast(); |
28 | } |
29 | if(!indexs.isEmpty() && indexs.getFirst() <= index - size) { |
30 | window.pollFirst(); |
31 | indexs.pollFirst(); |
32 | } |
33 | window.addLast(n); |
34 | indexs.addLast(index); |
35 | XORsum ^= window.getFirst(); |
36 | n = input.nextInt(); |
37 | index++; |
38 | } |
39 | System.out.printf("%d\n", XORsum); |
40 | } |
41 | } |
42 | |
43 | /************************************************************** |
44 | Problem: 1215 |
45 | User: |
46 | Language: Java |
47 | Result: Accepted |
48 | Time:1648 ms |
49 | Memory:47180 kb |
50 | ****************************************************************/ |
Problem D: Exciting Spider
Description
Ancient Spider is a very popular card game, and Vince loves to play it. Today he wants to play Ancient Spider again, but he changes the rule to make it more exciting. At the beginning of the game, Vince has an empty slot on the table. There are n different cards numbered from 1 to n, and Vince will receive them one by one in a given order and put the cards onto the top of the slot. At any time, Vince can pick up a card from the top of slot and discard it. If Vince discards all n cards, the game is over. Vince wants you to help him find the smallest lexicographical order among all possible discarding orders at the end of the game.
If you don’t know the concept of lexicographical order, you can see the reference in the following link: https://en.wikipedia.org/wiki/Lexicographical_order
Input
The first line is an integer $T$, which is the number of test cases.
Each test case contains two lines. The first line has an integer, $n$.
The second line contains a sequence A of length n, which is a permutation of 1 to n, representing the order Vince receives the cards.
($1\leq T\leq5, 1\leq n\leq 300000$)
Output
For each test case, print n integers in a line, which is the order discarding the card with the smallest lexicographical order.
Sample Input
1 | 2 |
2 | 3 |
3 | 1 3 2 |
4 | 4 |
5 | 3 4 1 2 |
Sample Output
1 | 1 2 3 |
2 | 1 2 4 3 |
Code
1 |
|
2 |
|
3 |
|
4 |
|
5 | |
6 | using namespace std; |
7 | |
8 | bool isUsed[300001]; |
9 | |
10 | int main() { |
11 | int testCase; |
12 | scanf("%d", &testCase); |
13 | while (testCase--) { |
14 | stack<int> slot; |
15 | queue<int> pile; |
16 | int size; |
17 | scanf("%d", &size); |
18 | for (int i = 0; i < size; i++) isUsed[i] = false; |
19 | int t; |
20 | int index = 0; |
21 | scanf("%d", &t); |
22 | while (t != 1) { |
23 | slot.push(t); |
24 | isUsed[t] = true; |
25 | scanf("%d", &t); |
26 | index++; |
27 | } |
28 | int toSearch = 1; |
29 | while (index < size) { |
30 | if (!slot.empty() && toSearch > slot.top()) { |
31 | pile.push(slot.top()); |
32 | slot.pop(); |
33 | } |
34 | else if (isUsed[toSearch]) { |
35 | if (toSearch != slot.top()) { |
36 | toSearch++; |
37 | continue; |
38 | } |
39 | else { |
40 | toSearch++; |
41 | pile.push(slot.top()); |
42 | slot.pop(); |
43 | } |
44 | } |
45 | else { |
46 | slot.push(t); |
47 | isUsed[t] = true; |
48 | if(index < size - 1) scanf("%d", &t); |
49 | index++; |
50 | } |
51 | } |
52 | while (!slot.empty()) { |
53 | pile.push(slot.top()); |
54 | slot.pop(); |
55 | } |
56 | while (!pile.empty()) { |
57 | printf("%d ", pile.front()); |
58 | pile.pop(); |
59 | } |
60 | printf("\n"); |
61 | } |
62 | return 0; |
63 | } |
64 | |
65 | /************************************************************** |
66 | Problem: 1175 |
67 | User: |
68 | Language: C++ |
69 | Result: Accepted |
70 | Time:472 ms |
71 | Memory:2756 kb |
72 | ****************************************************************/ |
Problem E: Magic Number
Description
There is a queue of n students, indexed from 1 to n from left to right. The height of every student has been given. Because students are standing on one stright line, for every student Ai in the queue, he can only see whom between him and the first student which is taller than him whether he looks left or right. Today teacher wants every student to find two partners, who are the highest one the student can see when he looks left and right respectively. Please help students find their partners. Notice that for every student the partners must shorter than himself.
Input
The first line is integer $T$ ($1≤T≤1000$), the number of test cases. Each test case consists of two lines. The first line is an integer $n$ ($0< n \leq 50000$) which represents the number of students. The second line lists the heights of students from left to right. It is guaranteed that heights of students are less than $2^{31} – 1$ and no two students share the same height in one queue.
Output
For each case, print the case number in one line. Then for every student in the testcase, print the index of his two partners in one line seprated by whitespace. If the eligible partner can not be found, the index should be 0. For example, for the student of height 5 in first testcase, he can not see anyone on his left so he can not find left parter and index should be 0. And because he is the highest one in the queue, he can see all the others on his right and the tallest one will be chosen as his right partner. so he choose the student with height 4 and index 3.
Sample Input
1 | 2 |
2 | 5 |
3 | 5 2 4 3 1 |
4 | 5 |
5 | 2 1 4 3 5 |
Sample Output
1 | Case 1: |
2 | 0 3 |
3 | 0 0 |
4 | 2 4 |
5 | 0 5 |
6 | 0 0 |
7 | Case 2: |
8 | 0 2 |
9 | 0 0 |
10 | 1 4 |
11 | 0 0 |
12 | 3 0 |
Code
1 |
|
2 |
|
3 |
|
4 |
|
5 | |
6 | using namespace std; |
7 | |
8 | int seq[50001]; |
9 | |
10 | int main() { |
11 | int testCase; |
12 | scanf("%d", &testCase); |
13 | for (int tc = 1; tc <= testCase; tc++) { |
14 | int size; |
15 | scanf("%d", &size); |
16 | for (int i = 1; i <= size; i++) scanf("%d", &seq[i]); |
17 | printf("Case %d:\n", tc); |
18 | stack<int> list; |
19 | queue<int> left; |
20 | for (int i = 1; i <= size; i++) { |
21 | if (list.empty()) { |
22 | list.push(i); |
23 | left.push(0); |
24 | } |
25 | else { |
26 | int aibo = 0; |
27 | while (!list.empty() && seq[list.top()] < seq[i]) { |
28 | aibo = list.top(); |
29 | list.pop(); |
30 | } |
31 | list.push(i); |
32 | left.push(aibo); |
33 | } |
34 | } |
35 | while (!list.empty()) list.pop(); |
36 | stack<int> right; |
37 | for (int i = size; i >= 1; i--) { |
38 | if (list.empty()) { |
39 | list.push(i); |
40 | right.push(0); |
41 | } |
42 | else { |
43 | int aibo = 0; |
44 | while (!list.empty() && seq[list.top()] < seq[i]) { |
45 | aibo = list.top(); |
46 | list.pop(); |
47 | } |
48 | list.push(i); |
49 | right.push(aibo); |
50 | } |
51 | } |
52 | while (!right.empty()) { |
53 | printf("%d %d\n", left.front(), right.top()); |
54 | left.pop(); |
55 | right.pop(); |
56 | } |
57 | } |
58 | return 0; |
59 | } |
60 | |
61 | /************************************************************** |
62 | Problem: 1270 |
63 | User: |
64 | Language: C++ |
65 | Result: Accepted |
66 | Time:912 ms |
67 | Memory:1452 kb |
68 | ****************************************************************/ |
Problem F: Magic Matrix
Description
A matrix is magic , if the difference between its maxmium and mimimum elements ≤ m. IceRuler has a large N×N matrix M. He would like to know size of the biggest magic sub-matrix of M.
Input
Input contains multiple testcases. The first line of Input contains a single integer $T$ ($1≤T≤1000$).The number of testcases. For each case,first line contains two numbers $N$ ($1≤N≤500$) and $M$($0≤M≤100000$),represent the given matrix is $N$ square matrix and magic equilibrium value is $M$. Each of the next $N$ rows contains $N$ integers, representing the large matrix. Elements are positive integers and not larger than $10^5$ . It is guaranteed that the sum of $N^3$ for all testcases is not exceed $2⋅10^8$.
Output
For each case, print size of the biggest magic sub-matrix of M in one line.
Sample Input
1 | 2 |
2 | 2 0 |
3 | 3 3 |
4 | 2 3 |
5 | 3 1 |
6 | 2 4 3 |
7 | 3 4 2 |
8 | 4 3 2 |
Sample Output
1 | 2 |
2 | 4 |
Problem G: Magic Calculator
Description
IceRuler has a magic calculator. It can calculate the answers for expressions, with constants only containing integers in the range 0-9 and operators only appearing in the following table.
Priority Level | Operator | Name | Combination Law | |
---|---|---|---|---|
1 | () | Bracket | ||
2 | + | Positive Sign | Right to left | |
- | Negative Sign | |||
~ | Bitwise Not | |||
3 | * | Multiplication | Left to Right | |
4 | + | Addition | Left to Right | |
- | Subtraction | Left to Right | ||
5 | & | Bitwise And | Left to Right | |
6 | ^ | Bitwise Xor | Left to Right | |
7 | \ | Bitwise Or | Left to Right |
Operators will be operated following their priority levels. For example, in 1+2&3, addition will be calculated first, then bitwise and. For 1-+2, positive sign will be calculated first, then subtraction.
Operators with same priority level will be operated following the combination law. For example, in 1+2-3, the combination law of addition and subtraction is “Left to Right”, addition should be calculated first, then subtraction. In -~1 , bitwisenot will be calculated first, then negative sign.
The expressions uses 32-bits signed integer type in the calculate process. You do not need to consider type conversion and overflow processing. For example, the result of ~1 should be -2, and the result of multiplying 2 by 32 times should be 0.
Please write a program to simulate the IceRuler’s calculator. Given expressions, you are required to return the results of this calculator.
Input
Integer $T$ in one line means testcases ($1≤T≤1000000$). For each case,you are given an expression in one line, and you should print its result in one line. The length of each expression is not exceed 50.
Output
You should print result of each expression in one line.
Sample Input
1 | 3 |
2 | 3&(2|1) |
3 | +-~3 |
4 | 2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2 |
Sample Output
1 | 3 |
2 | 4 |
3 | 0 |
Lab5_String
Problem A: How many substrings
Description
Give you a string, you should print how many none empty substrings it has.
Input
The first line is number of tests. $T$ ($1 \leq T \leq 10$)
The second line is a string S. The length of S doesn’t exceed $1000$, that is $|S| \leq 1000$
S will only contain lower case English letters.
Output
For each test, you should print an integer in a single line, which is the number of none empty substrings of S.
Sample Input
1 | 1 |
2 | hello |
Sample Output
1 | 15 |
HINT
Easy problem.
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | int main() { |
7 | int testCase; |
8 | scanf("%d", &testCase); |
9 | while (testCase--) { |
10 | char str[1000]; |
11 | scanf("%s", &str); |
12 | int len = 0; |
13 | while (str[len++] != '\0'); |
14 | len -= 1; |
15 | printf("%d\n", (1 + len) * len / 2); |
16 | } |
17 | return 0; |
18 | } |
19 | |
20 | /************************************************************** |
21 | Problem: 1045 |
22 | User: |
23 | Language: C++ |
24 | Result: Accepted |
25 | Time:0 ms |
26 | Memory:1092 kb |
27 | ****************************************************************/ |
Problem B: Matching Problem [Easy]
Description
Hong haves two strings s and t. The length of the string s equals n, the length of the string t equals m. The string s consists of lowercase letters and at most one wildcard character ‘*’, while the string t consists only of lowercase letters.
The wildcard character ‘‘ in the string s (if any) can be replaced with an arbitrary sequence (possibly void sequence) of lowercase letters. If it is possible to replace a wildcard character ‘‘ in s to obtain a string t, then the string t matches the pattern s.
If the given string t matches the given string s, print “YES”, otherwise print “NO”.
Input
The first line will be an integer $T$ ($1≤T≤10$), which is the number of test cases.
For each test data:
The first line contains two integers $n$ and $m$ ($1≤n, m≤2⋅10^5$) — the length of the string s and the length of the string t, respectively.
The second line contains string s of length n, which consists of lowercase letters and at most one wildcard character ‘*’.
The third line contains string t of length m, which consists only of lowercase letters.
Output
For each test cases, print “YES” (without quotes), if you can obtain the string t from the string s. Otherwise print “NO” (without quotes).
Sample Input
1 | 1 |
2 | 7 10 |
3 | aba*aba |
4 | abazzzzaba |
Sample Output
1 | YES |
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | int main() { |
7 | int testCase; |
8 | scanf("%d", &testCase); |
9 | while (testCase--) { |
10 | int str0len, str1len; |
11 | scanf("%d %d", &str0len, &str1len); |
12 | char* str0 = new char[str0len+1]; |
13 | char* str1 = new char[str1len+1]; |
14 | scanf("%s", str0); |
15 | scanf("%s", str1); |
16 | if (str0len - str1len > 1) { |
17 | printf("%s\n", "NO"); |
18 | continue; |
19 | } |
20 | int position = -1; |
21 | bool isSame = true; |
22 | while (position < str0len - 1 && str0[++position] != '*'); |
23 | if (position == str0len - 1 && str0[str0len - 1] != '*') { |
24 | if (str0len != str1len) isSame = false; |
25 | for (int i = 0; i < str0len; i++) { |
26 | if (str0[i] != str1[i]) { |
27 | isSame = false; |
28 | break; |
29 | } |
30 | } |
31 | } |
32 | else { |
33 | for (int i = 0; i < position; i++) { |
34 | if (str0[i] != str1[i]) { |
35 | isSame = false; |
36 | break; |
37 | } |
38 | } |
39 | for (int i = str0len - 1, j = str1len - 1; i > position; i--, j--) { |
40 | if (str0[i] != str1[j]) { |
41 | isSame = false; |
42 | break; |
43 | } |
44 | } |
45 | } |
46 | if(isSame) printf("%s\n", "YES"); |
47 | else printf("%s\n", "NO"); |
48 | delete[] str0; |
49 | delete[] str1; |
50 | } |
51 | return 0; |
52 | } |
53 | |
54 | /************************************************************** |
55 | Problem: 1146 |
56 | User: |
57 | Language: C++ |
58 | Result: Accepted |
59 | Time:12 ms |
60 | Memory:1596 kb |
61 | ****************************************************************/ |
Problem C: Repeat!
Description
Amayama finds that some “repeaters” have joined the computer science group. However, these people seem to update to the unordinary repeaters who only repeat part of the last sentence. Now, Amayama published some sentences in the group, and he wishes you to check out the number of “repeaters” who repeat him. He believes that if a person publishes a sentence that contains the prefix of the last one sentence, and this prefix is at least one-third the length of the last sentence (round up, e.g. for 100 then at least 34), then he is a “repeater”.
Input
The first line contains a number $N$, which is the number of suspicious accounts. ($1\leq N\leq 1000$) Then there are $2*N$ lines.
The $2*i-1$ line is a string s, which is the sentence published by Amayama. ($1\leq |s|\leq 10000$)
The $2*i$ line is a string p, which is the sentence published by a suspicious account. ($1\leq |p|\leq 10000$)
Output
The output contains an integer, which is the number of repeaters.
Sample Input
1 | 2 |
2 | lanranwudi |
3 | lanranwudi |
4 | aaa |
5 | bbcc |
Sample Output
1 | 1 |
HINT
The prefix of a string means a substring which must start from the first letter.
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | char saying[10001]; |
7 | char response[10001]; |
8 | int nextSeq[3400]; |
9 | |
10 | //int fastRead_string(char* str); |
11 | void generateNext(char* str); |
12 | bool KMP(char* matcher, int matcherLen, char* pattern); |
13 | |
14 | int getLen(char* str) { |
15 | int i = 0; |
16 | while (str[i++] != '\0'); |
17 | return i - 1; |
18 | } |
19 | |
20 | int main() { |
21 | int suspicious; |
22 | scanf("%d", &suspicious); |
23 | int repeaters = 0; |
24 | while (suspicious--) { |
25 | //int sayingLen = fastRead_string(saying); |
26 | //int responseLen = fastRead_string(response); |
27 | scanf("%s", saying); |
28 | int sayingLen = getLen(saying); |
29 | scanf("%s", response); |
30 | int responseLen = getLen(response); |
31 | nextSeq[0] = sayingLen / 3 + ((sayingLen % 3 == 0) ? 0 : 1); |
32 | generateNext(saying); |
33 | if (KMP(response, responseLen, saying)) repeaters += 1; |
34 | } |
35 | printf("%d\n", repeaters); |
36 | return 0; |
37 | } |
38 | |
39 | /* |
40 | int fastRead_string(char* str) { |
41 | char c; |
42 | int i = 0; |
43 | do c = getchar(); while (c < 33); |
44 | while (c != ' ' && c != '\n' && c != '\r' && c != '\t') { |
45 | str[i] = c; |
46 | c = getchar(); |
47 | i += 1; |
48 | } |
49 | str[i] = '\0'; |
50 | return i; |
51 | } |
52 | */ |
53 | |
54 | /* |
55 | void generateNext(char* str) { |
56 | nextSeq[1] = 0; |
57 | for (int i = 2, j = 0; i <= nextSeq[0];) { |
58 | if (j == 0 || str[i - 1] == str[j - 1]) nextSeq[i++] = j++; |
59 | else j = nextSeq[j]; |
60 | } |
61 | } |
62 | */ |
63 | |
64 | void generateNext(char* str) { |
65 | nextSeq[1] = 0; |
66 | for (int i = 2, j = 0; i <= nextSeq[0]; i++) { |
67 | while (j > 0 && str[j] != str[i - 1]) j = nextSeq[j]; |
68 | if (str[j] == str[i - 1]) j += 1; |
69 | nextSeq[i] = j; |
70 | } |
71 | } |
72 | |
73 | bool KMP(char* matcher, int matcherLen, char* pattern) { |
74 | for (int i = 0, j = 0; i < matcherLen; i++) { |
75 | while (j > 0 && matcher[i] != pattern[j]) j = nextSeq[j]; |
76 | if (matcher[i] == pattern[j]) j += 1; |
77 | if (j == nextSeq[0]) return true; |
78 | } |
79 | return false; |
80 | } |
81 | /************************************************************** |
82 | Problem: 1271 |
83 | User: |
84 | Language: C++ |
85 | Result: Accepted |
86 | Time:164 ms |
87 | Memory:1124 kb |
88 | ****************************************************************/ |
1 | import java.util.Scanner; |
2 | |
3 | public class Main { |
4 | public static void main(String[] args) { |
5 | Scanner input = new Scanner(System.in); |
6 | int suspicious = input.nextInt(); |
7 | int repeaters = 0; |
8 | while (suspicious-->0) { |
9 | String saying = input.next(); |
10 | String response = input.next(); |
11 | int[] nextSeq = new int[saying.length() / 3 + ((saying.length() % 3 == 0) ? 1 : 2)]; |
12 | nextSeq[0] = nextSeq.length - 1; |
13 | String pattern = saying.substring(0, nextSeq.length); |
14 | generateNext(nextSeq, pattern); |
15 | if(KMP(response, pattern, nextSeq)) repeaters += 1; |
16 | } |
17 | input.close(); |
18 | System.out.printf("%d\n", repeaters); |
19 | } |
20 | |
21 | private static void generateNext(int[] nextSeq, String str) { |
22 | nextSeq[1] = 0; |
23 | for(int k = 0, j = 2; j <= nextSeq[0]; j++) { |
24 | while (k > 0 && str.charAt(k) != str.charAt(j-1)) k = nextSeq[k]; |
25 | if (str.charAt(k) == str.charAt(j-1)) k += 1; |
26 | nextSeq[j] = k; |
27 | } |
28 | } |
29 | |
30 | private static boolean KMP(String matcher, String pattern, int[] nextSeq) { |
31 | int q = 0; |
32 | for(int i = 0; i < matcher.length(); i++) { |
33 | while (q > 0 && matcher.charAt(i) != pattern.charAt(q)) q = nextSeq[q]; |
34 | if(matcher.charAt(i) == pattern.charAt(q)) q += 1; |
35 | if(q == nextSeq[0]) return true; |
36 | } |
37 | return false; |
38 | } |
39 | } |
40 | |
41 | /************************************************************** |
42 | Problem: 1271 |
43 | User: |
44 | Language: Java |
45 | Result: Accepted |
46 | Time:864 ms |
47 | Memory:26232 kb |
48 | ****************************************************************/ |
1 | import java.util.Scanner; |
2 | import java.util.regex.Matcher; |
3 | import java.util.regex.Pattern; |
4 | |
5 | public class Main { |
6 | public static void main(String[] args) { |
7 | Scanner input = new Scanner(System.in); |
8 | int suspicious = input.nextInt(); |
9 | int repeaters = 0; |
10 | while (suspicious-->0) { |
11 | String saying = input.next(); |
12 | String response = input.next(); |
13 | Pattern pattern = Pattern.compile(saying.substring(0, saying.length() / 3 + ((saying.length() % 3 == 0) ? 0 : 1))); |
14 | Matcher matcher = pattern.matcher(response); |
15 | if (matcher.find()) repeaters += 1; |
16 | } |
17 | input.close(); |
18 | System.out.printf("%d\n", repeaters); |
19 | } |
20 | } |
21 | |
22 | /************************************************************** |
23 | Problem: 1271 |
24 | User: |
25 | Language: Java |
26 | Result: Accepted |
27 | Time:996 ms |
28 | Memory:43376 kb |
29 | ****************************************************************/ |
Problem D: Necklace!
Description
D1rtyPaw5 wants to drink coco with his girlfriend! Unfortunately, he has no girlfriend now, but he still wishes to prepare a necklace for his future goddess.
This is a kind of special necklace which contains a sequence of diamonds with letters in, and it can be regarded as a string. D1rtyPaw5 gives Amayama a semi-finished necklace and askes Amayama to add as few as possible diamonds to the head or tail of the necklace to make the necklace consist of at least two same circulation sections. A circulation section of a string is a substring which could build the original string by repeating the circulation section several times.
Please answer the number of diamonds that Amayama should add.
Input
The first line contains an integer n, which is the number of test cases. ($1\leq n\leq1000$)
For each case, there is only one line of string containing lowercase letters, which indicates the semi-finished necklace. The length of each string is no more than 200000.
Output
The output for each test case is an integer which is the number of diamonds that Amayama should add.
Sample Input
1 | 2 |
2 | wawawa |
3 | failed |
Sample Output
1 | 0 |
2 | 6 |
HINT
If a necklace has contained two circulation sections and ended with an uncomplete circulation section, you should complete this section to finish the whole necklace.
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | char necklace[200001]; |
7 | int nextSeq[200001]; |
8 | |
9 | int getLen(char* str); |
10 | void generateNext(char* str); |
11 | int getInFirstSeq(int index); |
12 | |
13 | int main() { |
14 | int testCase; |
15 | scanf("%d", &testCase); |
16 | while (testCase--) { |
17 | scanf("%s", necklace); |
18 | nextSeq[0] = getLen(necklace); |
19 | generateNext(necklace); |
20 | printf("%d\n", nextSeq[0] - nextSeq[nextSeq[0]] - getInFirstSeq(nextSeq[0])); |
21 | } |
22 | return 0; |
23 | } |
24 | |
25 | int getLen(char* str) { |
26 | int i = 0; |
27 | while (str[i++] != '\0'); |
28 | return i - 1; |
29 | } |
30 | |
31 | void generateNext(char* str) { |
32 | nextSeq[1] = 0; |
33 | for (int i = 2, j = 0; i <= nextSeq[0]; i++) { |
34 | while (j > 0 && str[j] != str[i - 1]) j = nextSeq[j]; |
35 | if (str[j] == str[i - 1]) j += 1; |
36 | nextSeq[i] = j; |
37 | } |
38 | } |
39 | |
40 | int getInFirstSeq(int index) { |
41 | if (nextSeq[index] == 0 && index == nextSeq[0]) return 0; |
42 | else if (index <= nextSeq[0] - nextSeq[nextSeq[0]]) return index; |
43 | else return getInFirstSeq(nextSeq[index]); |
44 | } |
45 | /************************************************************** |
46 | Problem: 1274 |
47 | User: |
48 | Language: C++ |
49 | Result: Accepted |
50 | Time:92 ms |
51 | Memory:2068 kb |
52 | ****************************************************************/ |
1 | import java.util.Scanner; |
2 | |
3 | public class Main { |
4 | public static void main(String[] args) { |
5 | Scanner input = new Scanner(System.in); |
6 | int testCase = input.nextInt(); |
7 | while(testCase-->0) { |
8 | String necklace = input.next(); |
9 | int[] nextSeq = new int[necklace.length()+1]; |
10 | nextSeq[0] = nextSeq.length - 1; |
11 | generateNext(nextSeq, necklace); |
12 | System.out.printf("%d\n", nextSeq[0] - nextSeq[nextSeq[0]] - getInFirstSeq(nextSeq, nextSeq[0])); |
13 | } |
14 | input.close(); |
15 | } |
16 | |
17 | private static void generateNext(int[] nextSeq, String str) { |
18 | nextSeq[1] = 0; |
19 | for(int k = 0, j = 2; j <= nextSeq[0]; j++) { |
20 | while (k > 0 && str.charAt(k) != str.charAt(j-1)) k = nextSeq[k]; |
21 | if (str.charAt(k) == str.charAt(j-1)) k += 1; |
22 | nextSeq[j] = k; |
23 | } |
24 | } |
25 | |
26 | private static int getInFirstSeq(int[] nextSeq, int index) { |
27 | if (nextSeq[index] == 0 && index == nextSeq[0]) return 0; |
28 | else if (index <= nextSeq[0] - nextSeq[nextSeq[0]]) return index; |
29 | else return getInFirstSeq(nextSeq, nextSeq[index]); |
30 | } |
31 | } |
32 | |
33 | /************************************************************** |
34 | Problem: 1274 |
35 | User: |
36 | Language: Java |
37 | Result: Accepted |
38 | Time:708 ms |
39 | Memory:36888 kb |
40 | ****************************************************************/ |
Problem E: Stick!
Description
Lovely boys often play stick game. This is a two-player game, which goal is finding the longest common substring of the two players’ names, and the length of it is defined as the stick level. Now, Amayama wants you help him to calculate the stick level between two boys.
Input
The input contains two string s1, s2 ($1\leq|s_1|,|s_2|\leq100000$), which are two lovely boys’ names.
Output
A number stands the sticking level.
Sample Input
1 | B.Tang |
2 | B.Tarjan |
Sample Output
1 | 4 |
HINT
https://en.wikipedia.org/wiki/Universal_hashing#Hashing_strings
Problem F: Resque!
Description
Special spy Oken was caught by the defenders of Narnal country. Before he got caught, Oken tries to send a half-encrypted message to his friend, Secsip. However, due to the obstruction of Amayama, some part of the message was broken. Secsip knows that Oken’s original message is a string, and he also knows the first half of the original message is an encryption of the second half using substitution cipher. The substitution cipher is a method of encrypting which replaces each letter in a string to another corresponding fixed letter in a bijection table which is known by Secsip. Now, Secsip receives the broken message, and he knows a suffix (which length could be 0) of the second half of the original message has been lost. He wishes to recover this lost suffix as short as possible.
A suffix of a string is a substring which ends with the last letter.
Input
The first line is the code table for the substitution cipher, which contains 26 letters representing the encrypted letter for each letter in lexicographical order.
The second line is a string which is the Oken’s broken message. The length of the string is no longer than 500000.
All letters in this problem is in lowercase.
Output
An integer which stands the length of second half of Oken’s original message with the lost suffix as short as possible.
Sample Input
1 | b c d e f g h i j k l m n o p q r s t u v w x y z a |
2 | bcdeabc |
Sample Output
1 | 4 |
HINT
For the sample input, the strategy which can recover the second half of the original message as short as possible is to add a “d” at the end of the broken message, so that the second half “abcd” can be encrypted to the first half “bcde” using the given encryption table.
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | char DecryptMap[26]; |
7 | char EncryptMap[26]; |
8 | char str[500001]; |
9 | char hal[250001]; |
10 | int nextSeq[250001]; |
11 | |
12 | int getLen(char* str); |
13 | char Encrypt(char c); |
14 | char Decrypt(char c); |
15 | void generateNext(char* str); |
16 | int KMP(char* matcher, int matcherLen, char* pattern); |
17 | |
18 | int main() { |
19 | for (int i = 0; i < 26; i++) { |
20 | scanf("%s", &str); |
21 | EncryptMap[i] = str[0]; |
22 | DecryptMap[str[0] - 'a'] = 'a' + i; |
23 | } |
24 | scanf("%s", str); |
25 | int len = getLen(str); |
26 | nextSeq[0] = len >> 1; |
27 | for (int i = 0; i < nextSeq[0]; i++) hal[i] = Decrypt(str[i]); |
28 | generateNext(hal); |
29 | printf("%d\n", len - KMP(str, len, hal)); |
30 | return 0; |
31 | } |
32 | |
33 | int getLen(char* str) { |
34 | int i = 0; |
35 | while (str[i++] != '\0'); |
36 | return i - 1; |
37 | } |
38 | |
39 | char Encrypt(char c) { |
40 | return EncryptMap[c - 'a']; |
41 | } |
42 | |
43 | char Decrypt(char c) { |
44 | return DecryptMap[c - 'a']; |
45 | } |
46 | |
47 | void generateNext(char* str) { |
48 | nextSeq[1] = 0; |
49 | for (int i = 2, j = 0; i <= nextSeq[0]; i++) { |
50 | while (j > 0 && str[j] != str[i - 1]) j = nextSeq[j]; |
51 | if (str[j] == str[i - 1]) j += 1; |
52 | nextSeq[i] = j; |
53 | } |
54 | } |
55 | |
56 | int KMP(char* matcher, int matcherLen, char* pattern) { |
57 | int j = 0; |
58 | for (int i = 0; i < matcherLen; i++) { |
59 | while (j > 0 && matcher[i] != pattern[j]) j = nextSeq[j]; |
60 | if (matcher[i] == pattern[j]) j += 1; |
61 | } |
62 | return j; |
63 | } |
64 | /************************************************************** |
65 | Problem: 1276 |
66 | User: |
67 | Language: C++ |
68 | Result: Accepted |
69 | Time:20 ms |
70 | Memory:2800 kb |
71 | ****************************************************************/ |
Lab6_Tree
Problem A: K-ary tree
Description
Given a complete K-ary tree with N nodes, please find the number of leaf nodes of this tree.
a K-ary tree is a rooted tree where every internal node has at most K child nodes, a K-ary tree of height h is complete if
- Level 0,1,…,h-1 are all full
- At level h, the leaf nodes are as far left as possible.
Input
The first line will be an integer $T$ ($1≤T≤1000$), which is the number of test cases.
For each test data:
The first line contains two integer $N$ ($2≤N≤108$) and $K$ ($2≤K≤100$) — the number of nodes, and the number child nodes it has at most.
Output
For each test cases, print one line with one integer, the number of leaf nodes of this tree
Sample Input
1 | 2 |
2 | 5 2 |
3 | 10 3 |
Sample Output
1 | 3 |
2 | 7 |
Code
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | typedef long long int lli; |
8 | |
9 | lli makePower(int base, int power) { |
10 | lli res = 1; |
11 | while (power--) res *= base; |
12 | return res; |
13 | } |
14 | |
15 | int main() { |
16 | int testCase; |
17 | scanf("%d", &testCase); |
18 | while (testCase--) { |
19 | lli nodes; |
20 | lli cnodes; |
21 | scanf("%lld %lld", &nodes, &cnodes); |
22 | int level = rint(floor(log2((cnodes - 1) * nodes + 1) / log2(cnodes))); |
23 | int lastLeaf = nodes - (makePower(cnodes, level) - 1) / (cnodes - 1); |
24 | int secondLeaf = makePower(cnodes, level - 1) - rint(ceil(lastLeaf / (double)cnodes)); |
25 | printf("%d\n", lastLeaf + secondLeaf); |
26 | } |
27 | return 0; |
28 | } |
29 | |
30 | /************************************************************** |
31 | Problem: 1277 |
32 | User: |
33 | Language: C++ |
34 | Result: Accepted |
35 | Time:0 ms |
36 | Memory:1120 kb |
37 | ****************************************************************/ |
1 |
|
2 |
|
3 |
|
4 | |
5 | typedef long long int lli; |
6 | |
7 | lli makePower(int base, int power) { |
8 | lli res = 1; |
9 | while (power--) res *= base; |
10 | return res; |
11 | } |
12 | |
13 | int main() { |
14 | int testCase; |
15 | scanf("%d", &testCase); |
16 | while (testCase--) { |
17 | lli nodes; |
18 | int cnodes; |
19 | scanf("%lld %d", &nodes, &cnodes); |
20 | int level = llrint(floor(log2((cnodes - 1) * nodes + 1) / log2(cnodes))); |
21 | int secondary = (makePower(cnodes, level) - 1) / (cnodes - 1); |
22 | int lastLeaf = nodes - (makePower(cnodes, level) - 1) / (cnodes - 1); |
23 | printf("%d\n", lastLeaf + makePower(cnodes, level - 1) - llrint(ceil(lastLeaf / (double)cnodes))); |
24 | } |
25 | return 0; |
26 | } |
27 | |
28 | /************************************************************** |
29 | Problem: 1277 |
30 | User: |
31 | Language: C |
32 | Result: Accepted |
33 | Time:0 ms |
34 | Memory:1120 kb |
35 | ****************************************************************/ |
Problem B: Find the depth
Description
Given a tree with $N$ nodes and $N-1$ edges, the length of each edge is 1, the root of the tree is node 1, please find the depth of all nodes. the depth for node 1 is 0.
Input
The first line will be a integer $T$ ($1≤T≤10$), which is the number of test cases.
For each test data:
The first line contains an integer $N$ ($1≤N≤10^5$) — the number of nodes.
the next N-1 lines contain two integers $a$ and $b$ ($1≤a,b≤N$), which means there is an edge between node $a$ and $b$.
Output
For each case, print one line with $N$ integers, the $i$-th integer indicates the depth of node i.
Sample Input
1 | 1 |
2 | 4 |
3 | 1 2 |
4 | 1 3 |
5 | 4 2 |
Sample Output
1 | 0 1 1 2 |
Code
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | void Trim(int parent, int node, int level); |
8 | vector<int> depth; |
9 | vector<vector<int>> Tree; |
10 | |
11 | int main() { |
12 | int testCase; |
13 | scanf("%i", &testCase); |
14 | while (testCase--) { |
15 | int nodes; |
16 | scanf("%i", &nodes); |
17 | Tree.clear(); |
18 | Tree.resize(nodes + 1); |
19 | depth.clear(); |
20 | depth.resize(nodes + 1); |
21 | depth[0] = nodes; |
22 | nodes -= 1; |
23 | while (nodes--) { |
24 | int a, b; |
25 | scanf("%i %i", &a, &b); |
26 | Tree[a].push_back(b); |
27 | Tree[b].push_back(a); |
28 | } |
29 | Trim(0, 1, -1); |
30 | for (int i = 1; i <= depth[0]; i++) printf("%i ", depth[i]); |
31 | printf("\n"); |
32 | } |
33 | return 0; |
34 | } |
35 | |
36 | void Trim(int parent, int node, int level) { |
37 | level += 1; |
38 | if (Tree[node].size() != 1 || node == 1) { |
39 | for (int i : Tree[node]) { |
40 | if (i != parent) { |
41 | Trim(node, i, level); |
42 | } |
43 | } |
44 | } |
45 | depth[node] = level; |
46 | } |
47 | |
48 | /************************************************************** |
49 | Problem: 1278 |
50 | User: |
51 | Language: C++ |
52 | Result: Accepted |
53 | Time:252 ms |
54 | Memory:9552 kb |
55 | ****************************************************************/ |
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | void Trim(int parent, int node, int level); |
8 | //vector<int> depth; |
9 | vector<vector<int>> Tree; |
10 | |
11 | int main() { |
12 | int testCase; |
13 | scanf("%i", &testCase); |
14 | while (testCase--) { |
15 | int nodes; |
16 | scanf("%i", &nodes); |
17 | Tree.clear(); |
18 | Tree.resize(nodes + 1); |
19 | //depth.clear(); |
20 | //depth.resize(nodes + 1); |
21 | //depth[0] = nodes; |
22 | nodes -= 1; |
23 | while (nodes--) { |
24 | int a, b; |
25 | scanf("%i %i", &a, &b); |
26 | Tree[a].push_back(b); |
27 | Tree[b].push_back(a); |
28 | } |
29 | Trim(0, 1, -1); |
30 | //for (int i = 1; i <= depth[0]; i++) printf("%i ", depth[i]); |
31 | for (int i = 1; i < Tree.size(); i++) printf("%i ", Tree[i][0]); |
32 | printf("\n"); |
33 | } |
34 | return 0; |
35 | } |
36 | |
37 | void Trim(int parent, int node, int level) { |
38 | level += 1; |
39 | if (Tree[node].size() != 1 || node == 1) { |
40 | for (int i : Tree[node]) { |
41 | if (i != parent) { |
42 | Trim(node, i, level); |
43 | } |
44 | } |
45 | } |
46 | //depth[node] = level; |
47 | Tree[node].insert(Tree[node].begin(), level); |
48 | } |
49 | |
50 | /************************************************************** |
51 | Problem: 1278 |
52 | User: |
53 | Language: C++ |
54 | Result: Accepted |
55 | Time:352 ms |
56 | Memory:9940 kb |
57 | ****************************************************************/ |
Problem C: Pre, in and post
Description
You are given the pre-order and in order traversal of the binary tree, please find the post-order of this tree.
Input
The first line will be an integer $T$ ($1≤T≤10$), which is the number of test cases.
For each test data:
The first line contains one integer $N$ ($1≤N≤10^3$) — the number of nodes of the tree
Then follows two lines:
The first line contains $N$ integers ranging from $1$ to $N$, indicating the pre-order traversal of the tree.
The second line contains $N$ integers ranging from $1$ to $N$, indicating the in-order traversal of the tree.
Output
For each case, contains one line with $N$ integer, the post-order traversal of the tree.
Sample Input
1 | 1 |
2 | 5 |
3 | 1 2 4 3 5 |
4 | 2 4 1 5 3 |
Sample Output
1 | 4 2 5 3 1 |
Code
1 |
|
2 |
|
3 | |
4 | using namespace std; |
5 | |
6 | int* preOrder; |
7 | int* inOrder; |
8 | |
9 | void postOrder(int preL, int preR, int inL, int inR); |
10 | |
11 | int main() { |
12 | int testCase; |
13 | scanf("%i", &testCase); |
14 | while (testCase--) { |
15 | int n; |
16 | scanf("%i", &n); |
17 | preOrder = new int[n + 1]; |
18 | inOrder = new int[n + 1]; |
19 | preOrder[0] = inOrder[0] = n; |
20 | for (int i = 1; i <= n; i++) scanf("%i", &preOrder[i]); |
21 | for (int i = 1; i <= n; i++) scanf("%i", &inOrder[i]); |
22 | postOrder(1, n, 1, n); |
23 | printf("\n"); |
24 | } |
25 | return 0; |
26 | } |
27 | |
28 | void postOrder(int preL, int preR, int inL, int inR) { |
29 | if(preL == preR) printf("%i ", inOrder[inR]); |
30 | else if (preL < preR) { |
31 | int root = inL - 1; |
32 | while (preOrder[preL] != inOrder[++root]); |
33 | int leftlen = root - inL; |
34 | postOrder(preL + 1, preL + leftlen, inL, root - 1); |
35 | postOrder(preL + leftlen + 1, preR, root + 1, inR); |
36 | printf("%i ", inOrder[root]); |
37 | } |
38 | } |
39 | /************************************************************** |
40 | Problem: 1279 |
41 | User: |
42 | Language: C++ |
43 | Result: Accepted |
44 | Time:0 ms |
45 | Memory:1216 kb |
46 | ****************************************************************/ |
1 |
|
2 |
|
3 |
|
4 | |
5 | int* preOrder; |
6 | int* inOrder; |
7 | |
8 | void postOrder(int preL, int preR, int inL, int inR); |
9 | |
10 | int main() { |
11 | int testCase; |
12 | scanf("%i", &testCase); |
13 | while (testCase--) { |
14 | int n; |
15 | scanf("%i", &n); |
16 | preOrder = (int*)calloc(n + 1, sizeof(int)); |
17 | inOrder = (int*)calloc(n + 1, sizeof(int)); |
18 | preOrder[0] = inOrder[0] = n; |
19 | for (int i = 1; i <= n; i++) scanf("%i", &preOrder[i]); |
20 | for (int i = 1; i <= n; i++) scanf("%i", &inOrder[i]); |
21 | postOrder(1, n, 1, n); |
22 | printf("\n"); |
23 | free(preOrder); |
24 | free(inOrder); |
25 | } |
26 | return 0; |
27 | } |
28 | |
29 | void postOrder(int preL, int preR, int inL, int inR) { |
30 | if (preL == preR) printf("%i ", inOrder[inR]); |
31 | else if (preL < preR) { |
32 | int root = inL - 1; |
33 | while (preOrder[preL] != inOrder[++root]); |
34 | int leftlen = root - inL; |
35 | postOrder(preL + 1, preL + leftlen, inL, root - 1); |
36 | postOrder(preL + leftlen + 1, preR, root + 1, inR); |
37 | printf("%i ", inOrder[root]); |
38 | } |
39 | } |
40 | /************************************************************** |
41 | Problem: 1279 |
42 | User: |
43 | Language: C |
44 | Result: Accepted |
45 | Time:0 ms |
46 | Memory:1092 kb |
47 | ****************************************************************/ |
Problem D: Cut the stick
Description
Lanran wants to cut one stick with length L into exactly N sticks with length $L_i$ ($i=1,2…,N$), so $L=∑L_i$. However, the cost to cut one stick in to two pieces is the length of the stick, that means cutting a stick with length x will cost x. Now he wants to know the minimal cost if he cuts stick optimally to get N sticks.
Input
The first line will be an integer $T$ ($1≤T≤100$), which is the number of test cases.
For each test data:
The first line contains an integer $N$ ($1≤N≤10^3$) — the number of sticks Lanran needs to get.
Then the next one line contains $N$ integers, the $i$-th integer $L_i$ ($1≤p_i≤10^5$) indicates the length of N sticks Lanran wants to get.
Output
For each case, contains one line, print the minimal minimal cost.
Sample Input
1 | 1 |
2 | 4 |
3 | 1 4 2 6 |
Sample Output
1 | 23 |
Code
1 | import java.util.ArrayList; |
2 | import java.util.Comparator; |
3 | import java.util.Scanner; |
4 | |
5 | public class Main { |
6 | public static void main(String[] args) { |
7 | ArrayList<Integer> sticks = new ArrayList<>(); |
8 | Scanner input = new Scanner(System.in); |
9 | int testCase = input.nextInt(); |
10 | while(testCase-->0) { |
11 | sticks.clear(); |
12 | int n = input.nextInt(); |
13 | while(n-->0) sticks.add(input.nextInt()); |
14 | int sum = 0; |
15 | while(sticks.size() != 1) { |
16 | sticks.sort(new Comparator<Integer>() { |
17 | |
18 | public int compare(Integer o1, Integer o2) { |
19 | return o2 - o1; |
20 | } |
21 | }); |
22 | int tmp = sticks.get(sticks.size() - 1) + sticks.get(sticks.size() - 2); |
23 | sticks.remove(sticks.size() - 1); |
24 | sticks.remove(sticks.size() - 1); |
25 | sticks.add(tmp); |
26 | sum += tmp; |
27 | } |
28 | System.out.printf("%d\n", sum); |
29 | } |
30 | } |
31 | } |
32 | |
33 | /************************************************************** |
34 | Problem: 1280 |
35 | User: |
36 | Language: Java |
37 | Result: Accepted |
38 | Time:404 ms |
39 | Memory:29132 kb |
40 | ****************************************************************/ |
Problem E: Cut a tree
Description
You are given a tree with $N$ nodes. Every node is colored with one color: white, red or blue. For every edge in tree, cutting this edge will get two smaller parts. If one of two smaller parts has no red node and the other one has no blue node, the edge is “valuable”.
It is guaranteed that there is at least one red node and one blue node.
You need to find the number of “valuable” edges.
Input
The first line will be an integer $T$ ($1≤T≤10$), which is the number of test cases.
For each test data:
The first line contains an integer $N$ ($1≤N≤10^5$) — the number of nodes.
The next $N-1$ lines contain two integers $a$ and $b$ ($1≤a,b≤N$), which means there is an edge between node a and b.
Then the next one line contains n integers, the $i$-th integer $p_i$ ($p_i=0,1,2$) indicates the color of node i. If $p_i=0$, the node is white. If $p_i=1$, the node is red. If $p_i=2$, the node is blue.
Output
For each case, contains one line, print the number of these edges.
Sample Input
1 | 3 |
2 | 4 |
3 | 1 2 |
4 | 2 3 |
5 | 2 4 |
6 | 1 0 0 2 |
7 | 5 |
8 | 1 2 |
9 | 2 3 |
10 | 3 4 |
11 | 4 5 |
12 | 2 0 0 0 1 |
13 | 3 |
14 | 1 2 |
15 | 2 3 |
16 | 1 2 1 |
Sample Output
1 | 2 |
2 | 4 |
3 | 0 |
Code
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | vector<vector<int>> Tree; |
8 | int totalColor[3]; |
9 | vector<vector<int>> nodeColor; |
10 | int valuableEdges; |
11 | |
12 | void Judge(int parent, int node); |
13 | |
14 | int main() { |
15 | int testCase; |
16 | scanf("%i", &testCase); |
17 | while (testCase--) { |
18 | int n; |
19 | scanf("%i", &n); |
20 | Tree.clear(); |
21 | Tree.resize(n + 1); |
22 | Tree[0].resize(n + 1); |
23 | Tree[0][0] = n; |
24 | totalColor[0] = totalColor[1] = totalColor[2] = 0; |
25 | nodeColor.clear(); |
26 | nodeColor.resize(n + 1); |
27 | for (int i = 1; i < n; i++) { |
28 | int a, b; |
29 | scanf("%i %i", &a, &b); |
30 | Tree[a].push_back(b); |
31 | Tree[b].push_back(a); |
32 | } |
33 | for (int i = 1; i <= n; i++) { |
34 | scanf("%i", &Tree[0][i]); |
35 | totalColor[Tree[0][i]] += 1; |
36 | } |
37 | valuableEdges = 0; |
38 | Judge(0, 1); |
39 | printf("%i\n", valuableEdges); |
40 | } |
41 | return 0; |
42 | } |
43 | |
44 | void Judge(int parent, int node) { |
45 | nodeColor[node].clear(); |
46 | nodeColor[node].resize(3); |
47 | if (Tree[node].size() != 1 || node == 1) { |
48 | for (auto i : Tree[node]) { |
49 | if (i != parent) { |
50 | Judge(node, i); |
51 | nodeColor[node][0] += nodeColor[i][0]; |
52 | nodeColor[node][1] += nodeColor[i][1]; |
53 | nodeColor[node][2] += nodeColor[i][2]; |
54 | if (totalColor[1] == nodeColor[i][1] || totalColor[2] == nodeColor[i][2]) if(nodeColor[i][1] == 0 || nodeColor[i][2] == 0) valuableEdges += 1; |
55 | } |
56 | } |
57 | } |
58 | nodeColor[node][Tree[0][node]] += 1; |
59 | } |
60 | /************************************************************** |
61 | Problem: 1281 |
62 | User: |
63 | Language: C++ |
64 | Result: Accepted |
65 | Time:416 ms |
66 | Memory:14468 kb |
67 | ****************************************************************/ |
Problem F: K people travel on a tree
Description
There are N cities numbered from 1 to N and N-1 roads connecting these N cities, or consider it is a tree with N nodes. Each road takes 1 day to travel through. There are K people initially stays at different K cities. They decide to meet at the same city as soon as possible. Please find the minimal time needed.
Input
The first line will be an integer $T$ ($1≤T≤10$), which is the number of test cases.
For each test data:
The first line contains two integers $N$ ($1≤N≤10^5$) and $K$ ($1≤K≤N$) — the number of cities and the number of friends.
The next $N - 1$ lines contain two integers A and B, which means there is a road between city A and city B.
Then the next one line contains $K$ integers, the $i$-th integer $p_i$ indicates the place they initially stay.
Output
For each case, contains one line, print the minimal time.
Sample Input
1 | 1 |
2 | 4 2 |
3 | 1 2 |
4 | 2 4 |
5 | 2 3 |
6 | 1 3 |
Sample Output
1 | 1 |
Lab7_Advanced_Tree
Problem A: Complete binary tree [Easy I]
Description
Lanran has a binary tree with $n$ nodes, she does not know whether this tree is a complete binary tree or not. She turns to you for help. We guarantee that the input is a binary tree.
Input
The first line will be an integer $T$, which is the number of the test cases.($1≤T≤14$) For each test case, the first line will be an integer $n$.($1≤n≤150000$)Then followed by $n$ lines, each line will be two integers $x$ and $y$, the $i$-th line means the left child of node $i$ is $x$, the right child of node $i$ is $y$. If node $i$ has no left child, then $x$ will be 0. If node $i$ has no right child, then $y$ will be 0.
Output
For each test output Yes or No in one line.
Sample Input
1 | 1 |
2 | 5 |
3 | 2 3 |
4 | 4 0 |
5 | 5 0 |
6 | 0 0 |
7 | 0 0 |
Sample Output
1 | No |
Code
1 |
|
2 |
|
3 |
|
4 |
|
5 | |
6 | using namespace std; |
7 | |
8 | struct Node { |
9 | bool isRoot; |
10 | Node* left; |
11 | Node* right; |
12 | Node() { |
13 | this->isRoot = true; |
14 | this->left = this->right = NULL; |
15 | } |
16 | }; |
17 | |
18 | bool isCompleteBinaryTree(Node* root); |
19 | void deletTree(Node* root); |
20 | |
21 | vector<Node*> Tree; |
22 | |
23 | int main() { |
24 | int testCase; |
25 | scanf("%i", &testCase); |
26 | while (testCase--) { |
27 | int n; |
28 | scanf("%i", &n); |
29 | Tree.resize(n + 1); |
30 | for (int i = 0; i <= n; i++) Tree[i] = new Node(); |
31 | for (int i = 1, a, b; i <= n; i++) { |
32 | scanf("%i %i", &a, &b); |
33 | Tree[i]->left = Tree[a]; |
34 | Tree[i]->right = Tree[b]; |
35 | Tree[a]->isRoot = false; |
36 | Tree[b]->isRoot = false; |
37 | } |
38 | Node* root = Tree[0]; |
39 | for (int i = 1; i <= n; i++) { |
40 | if (Tree[i]->isRoot) { |
41 | root = Tree[i]; |
42 | break; |
43 | } |
44 | } |
45 | if (isCompleteBinaryTree(root)) printf("Yes\n"); |
46 | else printf("No\n"); |
47 | deletTree(root); |
48 | } |
49 | return 0; |
50 | } |
51 | |
52 | queue<Node*> shell; |
53 | |
54 | bool isCompleteBinaryTree(Node* root) { |
55 | while (!shell.empty()) shell.pop(); |
56 | shell.push(root); |
57 | while (!shell.empty()) { |
58 | if (shell.front()->right != Tree[0]) { |
59 | if (shell.front()->left != Tree[0]) { |
60 | shell.push(shell.front()->left); |
61 | shell.push(shell.front()->right); |
62 | shell.pop(); |
63 | } |
64 | else return false; |
65 | } |
66 | else { |
67 | if (shell.front()->left != Tree[0]) { |
68 | shell.push(shell.front()->left); |
69 | shell.pop(); |
70 | } |
71 | while (!shell.empty()) { |
72 | if (shell.front()->right == Tree[0] && shell.front()->left == Tree[0]) shell.pop(); |
73 | else return false; |
74 | } |
75 | } |
76 | } |
77 | return true; |
78 | } |
79 | |
80 | void deletTree(Node* root) { |
81 | while (!shell.empty()) shell.pop(); |
82 | shell.push(root); |
83 | while (!shell.empty()) { |
84 | if (shell.front()->left != Tree[0]) shell.push(shell.front()->left); |
85 | if (shell.front()->right != Tree[0]) shell.push(shell.front()->right); |
86 | delete shell.front(); |
87 | shell.pop(); |
88 | } |
89 | } |
90 | /************************************************************** |
91 | Problem: 1121 |
92 | User: |
93 | Language: C++ |
94 | Result: Accepted |
95 | Time:524 ms |
96 | Memory:6896 kb |
97 | ****************************************************************/ |
Problem B: Judgement [Easy II]
Description
Please judge whether the given tree is a binary heap.
A binary heap is defined as a binary tree with two additional constraints:
- Shape property: a binary heap is a complete binary tree
- Heap property: the value stored in each node is either greater than or equal to (≥) or less than or equal to (≤) the the values in the node’s children
Input
The first line will be an integer $T$,which is the number of test cases.($1≤T≤10$) For each test case, the first line will be an integer $n$ ($1≤n≤105$).
The second line will be $n$ integers, $a_1,a_2,⋯,a_n$($1≤a_i≤10^9$). $a_i$ represents the value of the $i$-th node, then followed by $n−1$ lines, each line will be two integers $x$ and $y$, which means $y$-th node is a child of $x$-th node. Besides, The left child will appear first (The order of appearance of child nodes is from left to right).
Output
For each test, print the number of the test cases first, then print YES when the tree is a binary heap, else print NO.
We guarantee that $1≤x,y≤n$ and input is a tree.
Sample Input
1 | 3 |
2 | 4 |
3 | 1 2 3 4 |
4 | 3 1 |
5 | 3 4 |
6 | 3 2 |
7 | 3 |
8 | 2 1 3 |
9 | 2 1 |
10 | 2 3 |
11 | 3 |
12 | 2 1 3 |
13 | 3 1 |
14 | 3 2 |
Sample Output
1 | Case #1: NO |
2 | Case #2: YES |
3 | Case #3: YES |
Code
1 |
|
2 | |
3 |
|
4 |
|
5 |
|
6 | |
7 | using namespace std; |
8 | |
9 | vector<vector<int>> Tree; |
10 | vector<bool> notRoot; |
11 | |
12 | bool minmaxConsist; |
13 | int minmax[3]; |
14 | bool Jugdement(int root); |
15 | |
16 | int main() { |
17 | int testCase; |
18 | scanf("%i", &testCase); |
19 | for(int tc = 1; tc <= testCase; tc++) { |
20 | int n; |
21 | scanf("%i", &n); |
22 | notRoot.clear(); |
23 | notRoot.resize(n + 1); |
24 | Tree.clear(); |
25 | Tree.resize(n + 1); |
26 | Tree[0].push_back(n); |
27 | for (int i = 1, tmp; i <= n; i++) { |
28 | scanf("%i", &tmp); |
29 | Tree[i].push_back(tmp); |
30 | } |
31 | for (int a, b; n-->1;) { |
32 | scanf("%i %i", &a, &b); |
33 | Tree[a].push_back(b); |
34 | notRoot[b] = true; |
35 | } |
36 | int root = 0; |
37 | bool isCBT = true; |
38 | for (int i = 1; i <= Tree[0][0]; i++) { |
39 | if(!notRoot[i]) root = i; |
40 | if(Tree[i].size() > 3) isCBT = false; |
41 | } |
42 | if(root == 0 || !isCBT) { |
43 | printf("Case #%i: NO\n", tc); |
44 | continue; |
45 | } |
46 | minmax[0] = minmax[1] = minmax[2] = 0; |
47 | isCBT = Jugdement(root); |
48 | if(isCBT && ((minmax[1] == 0 && minmax[2] != 0) || (minmax[1] != 0 && minmax[2] == 0))) printf("Case #%i: YES\n", tc); |
49 | else printf("Case #%i: NO\n", tc); |
50 | } |
51 | return 0; |
52 | } |
53 | |
54 | void JudgeMinMax(vector<int>* root) { |
55 | switch (root->size()) { |
56 | case 3: { |
57 | if (Tree[root->at(2)][0] > root->at(0)) minmax[1] += 1; |
58 | else if (Tree[root->at(2)][0] < root->at(0)) minmax[2] += 1; |
59 | else minmax[0] += 1; |
60 | } |
61 | case 2: { |
62 | if (Tree[root->at(1)][0] > root->at(0)) minmax[1] += 1; |
63 | else if (Tree[root->at(1)][0] < root->at(0)) minmax[2] += 1; |
64 | else minmax[0] += 1; |
65 | } |
66 | } |
67 | } |
68 | |
69 | queue<vector<int>*> shell; |
70 | |
71 | bool Jugdement(int root) { |
72 | while (!shell.empty()) shell.pop(); |
73 | shell.push(&Tree[root]); |
74 | while (!shell.empty()) { |
75 | switch (shell.front()->size()) { |
76 | case 3:{ |
77 | shell.push(&Tree[shell.front()->at(1)]); |
78 | shell.push(&Tree[shell.front()->at(2)]); |
79 | JudgeMinMax(shell.front()); |
80 | shell.pop(); |
81 | break; |
82 | } |
83 | case 2: { |
84 | shell.push(&Tree[shell.front()->at(1)]); |
85 | JudgeMinMax(shell.front()); |
86 | shell.pop(); |
87 | } |
88 | case 1: { |
89 | while (!shell.empty()) { |
90 | if(shell.front()->size() == 1) shell.pop(); |
91 | else return false; |
92 | } |
93 | } |
94 | } |
95 | } |
96 | return true; |
97 | } |
98 | /************************************************************** |
99 | Problem: 1282 |
100 | User: |
101 | Language: C++ |
102 | Result: Accepted |
103 | Time:792 ms |
104 | Memory:7184 kb |
105 | ****************************************************************/ |
Problem C: Cut The Stick Pro [Middle I]
Description
Lanran wants to cut one stick with length $L$ into exactly $N$ sticks with length $L_i(i=1,2…N)$, so $L=∑^N_{i=1}Li$. However, the cost to cut one stick into two pieces is the length of the stick, which means cutting a stick with length $x$ will cost $x$. Now he wants to know the minimal cost if he cuts stick optimally to get N sticks.
Input
The first line will be an integer $T$ ($1≤T≤5$), which is the number of test cases.
For each test, the first line contains an integer $N$ ($1≤N≤10^5$) — the number of sticks Lanran needs to get. Then the next line contains $N$ integers, the $i$-th integer $L_i$ ($1≤pi≤10^5$) indicates the length of $N$ sticks Lanran wants to get.
Output
For each case print the minimal cost if Lanran cuts stick optimally to get $N$ sticks.
Sample Input
1 | 1 |
2 | 4 |
3 | 1 4 2 6 |
Sample Output
1 | 23 |
Code
1 |
|
2 |
|
3 |
|
4 | |
5 | using namespace std; |
6 | |
7 | typedef long long int lli; |
8 | |
9 | priority_queue<lli, vector<lli>, greater<lli>> sticks; |
10 | |
11 | int main() { |
12 | int testCase; |
13 | scanf("%i", &testCase); |
14 | while (testCase--) { |
15 | int n; |
16 | scanf("%i", &n); |
17 | while (n--) { |
18 | lli tmp; |
19 | scanf("%lli", &tmp); |
20 | sticks.push(tmp); |
21 | } |
22 | lli Ssum = 0; |
23 | while (sticks.size() != 1) { |
24 | lli tmp = sticks.top(); |
25 | sticks.pop(); |
26 | tmp += sticks.top(); |
27 | sticks.pop(); |
28 | sticks.push(tmp); |
29 | Ssum += tmp; |
30 | } |
31 | printf("%lli\n", Ssum); |
32 | while(!sticks.empty()) sticks.pop(); |
33 | } |
34 | return 0; |
35 | } |
36 | |
37 | /************************************************************** |
38 | Problem: 1283 |
39 | User: |
40 | Language: C++ |
41 | Result: Accepted |
42 | Time:792 ms |
43 | Memory:2788 kb |
44 | ****************************************************************/ |
Problem D: Stream Processing [Middle II]
Description
VinceBlack is working on stream processing. There is now an infinite stream of data that can be thought of as producing an integer per second. Your task is to collect each number and then output the current $k$th largest number (for all the numbers collected) every 100 seconds . If the currently collected number is less than $k$, the smallest number is output.
The $k$th largest number indicates that if sorted in descending order, this number will be ranked in the $k$th position.
Input
The input contains three integers $t$ ($100≤t≤10^6$), $k$ ($1≤k≤1000$) and $s$ ($0≤s≤10^5$).
t is the number of seconds you need to process
Define $a(n)=n+sum of the digits of n$, and the number appearing at $i$-th ($i$ starts at 1) second in the data stream is $a(i+last_ans)$.
$last_ans=s$ in the beginning and will be updated after each answer is calculated.
Output
$⌊t/100⌋$ integers in a line, represents the answers in each 100 seconds.
Sample Input
1 | 1926 8 17 |
Sample Output
1 | 117 319 623 1024 1529 2131 2840 3649 4559 5571 6686 7906 9219 10624 12127 13737 15447 17258 19171 |
HINT
More information about a(n): ref
Code
1 |
|
2 | |
3 |
|
4 |
|
5 | |
6 | using namespace std; |
7 | |
8 | typedef long long int lli; |
9 | |
10 | lli A062028(lli n); |
11 | |
12 | int main() { |
13 | lli t, k, s; |
14 | scanf("%lli %lli %lli", &t, &k, &s); |
15 | priority_queue<lli, vector<lli>, greater<lli>> pq; |
16 | for(int i = 1; i <= t; i++) { |
17 | auto tmp = A062028(i + s); |
18 | if(pq.size() < k) pq.push(tmp); |
19 | else if(tmp > pq.top()) { |
20 | pq.pop(); |
21 | pq.push(tmp); |
22 | } |
23 | if(i % 100 == 0) { |
24 | printf("%lli ", pq.top()); |
25 | s = pq.top(); |
26 | } |
27 | } |
28 | return 0; |
29 | } |
30 | |
31 | lli A062028(lli n) { |
32 | lli res = n; |
33 | while (n != 0) { |
34 | res += n % 10; |
35 | n /= 10; |
36 | } |
37 | return res; |
38 | } |
39 | |
40 | /************************************************************** |
41 | Problem: 1285 |
42 | User: |
43 | Language: C++ |
44 | Result: Accepted |
45 | Time:508 ms |
46 | Memory:1252 kb |
47 | ****************************************************************/ |
1 | import java.util.PriorityQueue; |
2 | import java.util.Queue; |
3 | import java.util.Scanner; |
4 | |
5 | public class Main { |
6 | public static void main(String[] args) { |
7 | Scanner input = new Scanner(System.in); |
8 | long t = input.nextInt(), k = input.nextInt(), s = input.nextInt(); |
9 | Queue<Long> pq = new PriorityQueue<>(); |
10 | for(int i = 1; i <= t; i++) { |
11 | long tmp = A062028(i + s); |
12 | if(pq.size() < k) pq.offer(tmp); |
13 | else if(tmp > pq.peek()) { |
14 | pq.poll(); |
15 | pq.offer(tmp); |
16 | } |
17 | if(i % 100 == 0) { |
18 | System.out.printf("%d ", pq.peek()); |
19 | s = pq.peek(); |
20 | } |
21 | } |
22 | } |
23 | |
24 | private static long A062028(long n) { |
25 | long res = n; |
26 | while(n != 0) { |
27 | res += n % 10; |
28 | n /= 10; |
29 | } |
30 | return res; |
31 | } |
32 | } |
33 | |
34 | /************************************************************** |
35 | Problem: 1285 |
36 | User: |
37 | Language: Java |
38 | Result: Accepted |
39 | Time:816 ms |
40 | Memory:83224 kb |
41 | ****************************************************************/ |
Problem E: Nth Element in Sliding Window [Hard I]
Description
Given a sequence $a_1,a_2,⋯,a_m$, there is a sliding window of size $k$ from the very left of the sequence to the very right. You can only see the $k$ numbers in the window. Each time the sliding window moves right by one position.
For each time there is $a_n$ integer $n_i$, you are asked the $n_i$-th element in the window. The $k$-th element indicates that the element will be in the $k$-th position after sorting in ascending order.
Input
The first line contains two integers $m$ and $k$, ($1≤m ≤105,1≤k≤m$)
The second line contains m distinct integers separated by space $a_i$ ($−2147483648≤ai≤2147483647$).
The next line contains $m−k+1$ integers separated by space $n_i$ ($1≤n_i≤k$)
Output
Output $m−k+1$ lines, each line contain a number represented the answer to each window
Sample Input
1 | 6 3 |
2 | 201 91 29 13 11 -5 |
3 | 3 1 2 1 |
Sample Output
1 | 201 |
2 | 13 |
3 | 13 |
4 | -5 |
HINT
Balanced binary search tree
Code
1 |
|
2 | |
3 |
|
4 |
|
5 |
|
6 | |
7 | using namespace std; |
8 | |
9 | typedef long long int lli; |
10 | |
11 | class AVLTree { |
12 | private: |
13 | struct Node { |
14 | lli key, height, size; |
15 | Node* left, * right; |
16 | explicit Node(lli key) { |
17 | this->key = key; |
18 | this->height = 0; |
19 | this->size = 1; |
20 | this->left = this->right = nullptr; |
21 | } |
22 | |
23 | static lli getHeight(Node* node) { |
24 | if (node == nullptr) return -1; |
25 | return node->height; |
26 | } |
27 | |
28 | static lli getSize(Node* node) { |
29 | if (node == nullptr) return 0; |
30 | return node->size; |
31 | } |
32 | |
33 | void updateSize() { this->size = 1 + getSize(this->left) + getSize(this->right); } |
34 | |
35 | void updateHeight() { this->height = 1 + max(getHeight(this->left), getHeight(this->right)); } |
36 | }; |
37 | |
38 | static Node* rotateRight(Node* node) { |
39 | auto tmp = node->left; |
40 | node->left = tmp->right; |
41 | tmp->right = node; |
42 | tmp->size = node->size; |
43 | node->updateSize(); |
44 | node->updateHeight(); |
45 | tmp->updateHeight(); |
46 | return tmp; |
47 | } |
48 | |
49 | static Node* rotateLeft(Node* node) { |
50 | auto tmp = node->right; |
51 | node->right = tmp->left; |
52 | tmp->left = node; |
53 | tmp->size = node->size; |
54 | node->updateSize(); |
55 | node->updateHeight(); |
56 | tmp->updateHeight(); |
57 | return tmp; |
58 | } |
59 | |
60 | static lli getBalanceFactor(Node* node) { |
61 | if(node == nullptr) return 0; |
62 | return Node::getHeight(node->left) - Node::getHeight(node->right); |
63 | } |
64 | |
65 | static Node* balance(Node* node) { |
66 | if (getBalanceFactor(node) < -1) { |
67 | if (getBalanceFactor(node->right) > 0) node->right = rotateRight(node->right); |
68 | node = rotateLeft(node); |
69 | } |
70 | else if (getBalanceFactor(node) > 1) { |
71 | if (getBalanceFactor(node->left) < 0) node->left = rotateLeft(node->left); |
72 | node = rotateRight(node); |
73 | } |
74 | return node; |
75 | } |
76 | |
77 | static Node* add(Node* node, lli key) { |
78 | if (node == nullptr) return new Node(key); |
79 | lli cmp = key - node->key; |
80 | if (cmp < 0) node->left = add(node->left, key); |
81 | else if (cmp > 0) node->right = add(node->right, key); |
82 | node->updateSize(); |
83 | node->updateHeight(); |
84 | return balance(node); |
85 | } |
86 | |
87 | static Node* min(Node* node) { |
88 | if (node->left == nullptr) return node; |
89 | return min(node->left); |
90 | } |
91 | |
92 | static Node* deleteMin(Node* node) { |
93 | if (node->left == nullptr) return node->right; |
94 | node->left = deleteMin(node->left); |
95 | node->updateSize(); |
96 | node->updateHeight(); |
97 | return balance(node); |
98 | } |
99 | |
100 | static Node* deleteNode(Node* node, lli key) { |
101 | lli cmp = key - node->key; |
102 | if (cmp < 0) node->left = deleteNode(node->left, key); |
103 | else if (cmp > 0) node->right = deleteNode(node->right, key); |
104 | else { |
105 | if (node->left == nullptr || node->right == nullptr) { |
106 | auto tmp = node->left ? node->left : node->right; |
107 | free(node); |
108 | return tmp; |
109 | } |
110 | else { |
111 | auto tmp = node; |
112 | auto toFree = node; |
113 | node = min(tmp->right); |
114 | node->right = deleteMin(tmp->right); |
115 | node->left = tmp->left; |
116 | free(toFree); |
117 | } |
118 | } |
119 | node->updateSize(); |
120 | node->updateHeight(); |
121 | return balance(node); |
122 | } |
123 | |
124 | lli find(Node* node, lli index) { |
125 | if(node == nullptr) return 0; |
126 | if(Node::getSize(node->left) > index) return this->find(node->left, index); |
127 | else if(Node::getSize(node->left) < index) return this->find(node->right, index - Node::getSize(node->left) - 1); |
128 | return node->key; |
129 | } |
130 | |
131 | lli size; |
132 | Node* root; |
133 | |
134 | public: |
135 | AVLTree() { |
136 | this->size = 0; |
137 | this->root = nullptr; |
138 | } |
139 | |
140 | lli getSize() { return size; } |
141 | |
142 | void add(lli key) { |
143 | this->size += 1; |
144 | if (this->size == 1) this->root = new Node(key); |
145 | else this->root = AVLTree::add(this->root, key); |
146 | } |
147 | |
148 | void deleteNode(lli key) { |
149 | this->size -= 1; |
150 | this->root = AVLTree::deleteNode(this->root, key); |
151 | } |
152 | |
153 | lli find(lli key) { return this->find(this->root, key - 1); } |
154 | }; |
155 | |
156 | int main() { |
157 | int m, k; |
158 | scanf("%i %i", &m, &k); |
159 | vector<lli> array(m); |
160 | for(lli i = 0; i < m; i++) scanf("%lli", &array[i]); |
161 | AVLTree tree = AVLTree(); |
162 | int id; |
163 | for(id = 0; tree.getSize() < k - 1; id++) tree.add(array[id]); |
164 | for(lli tmp; id < m; id++) { |
165 | tree.add(array[id]); |
166 | scanf("%lli", &tmp); |
167 | printf("%lli\n", tree.find(tmp)); |
168 | tree.deleteNode(array[id - k + 1]); |
169 | } |
170 | return 0; |
171 | } |
172 | |
173 | /************************************************************** |
174 | Problem: 1203 |
175 | User: |
176 | Language: C++ |
177 | Result: Accepted |
178 | Time:180 ms |
179 | Memory:2428 kb |
180 | ****************************************************************/ |
1 | import java.io.BufferedReader; |
2 | import java.io.IOException; |
3 | import java.io.InputStream; |
4 | import java.io.InputStreamReader; |
5 | import java.util.StringTokenizer; |
6 | |
7 | public class Main { |
8 | public static void main(String[] args) { |
9 | InputReader input = new InputReader(System.in); |
10 | long m = input.nextInt(), k = input.nextInt(); |
11 | long[] array = new long[(int)m]; |
12 | for(long i = 0; i < m; i++) array[(int)i] = input.nextLong(); |
13 | AVLTree tree = new AVLTree(); |
14 | long id; |
15 | for(id = 0; tree.getSize() < k - 1; id++) tree.add(array[(int)id]); |
16 | for(long tmp; id < m; id++){ |
17 | tree.add(array[(int)id]); |
18 | tmp = input.nextInt(); |
19 | System.out.printf("%d\n", tree.find(tmp)); |
20 | tree.delete(array[(int)(id - k + 1)]); |
21 | } |
22 | } |
23 | |
24 | private static class InputReader { |
25 | private BufferedReader reader; |
26 | private StringTokenizer tokenizer; |
27 | |
28 | InputReader(InputStream stream) { |
29 | reader = new BufferedReader(new InputStreamReader(stream), 32768); |
30 | tokenizer = null; |
31 | } |
32 | |
33 | private String next() { |
34 | while(tokenizer == null || !tokenizer.hasMoreTokens()) { |
35 | try { tokenizer = new StringTokenizer(reader.readLine()); } |
36 | catch (IOException e) { throw new RuntimeException(e); } |
37 | } |
38 | return tokenizer.nextToken(); |
39 | } |
40 | |
41 | public long nextInt() { |
42 | return Integer.parseInt(next()); |
43 | } |
44 | |
45 | public long nextLong() { |
46 | return Long.parseLong(this.next()); |
47 | } |
48 | } |
49 | |
50 | private static class AVLTree { |
51 | private long size; |
52 | private Node root; |
53 | |
54 | AVLTree() { |
55 | this.size = 0; |
56 | this.root = null; |
57 | } |
58 | |
59 | public long getSize() { |
60 | return size; |
61 | } |
62 | |
63 | public void add(long key) { |
64 | this.size += 1; |
65 | if (this.size == 1) this.root = new Node(key); |
66 | else this.root = this.add(this.root, key); |
67 | } |
68 | |
69 | public void delete(long key) { |
70 | if (this.get(key) == null) return;//TODO |
71 | this.size -= 1; |
72 | this.root = this.delete(this.root, key); |
73 | } |
74 | |
75 | private long find(Node node, long index) { |
76 | if(node == null) return 0; |
77 | if(Node.size(node.left) > index) return this.find(node.left, index); |
78 | else if(Node.size(node.left) < index) return this.find(node.right, index - Node.size(node.left) - 1); |
79 | return node.key; |
80 | } |
81 | |
82 | public long find(long key) { |
83 | return this.find(this.root, key - 1); |
84 | } |
85 | |
86 | private static class Node { |
87 | long key, height, size; |
88 | Node left, right; |
89 | Node(long key) { |
90 | this.key = key; |
91 | this.height = 0; |
92 | this.size = 1; |
93 | this.left = this.right = null; |
94 | } |
95 | |
96 | private static long height(Node node) { |
97 | if (node == null) return -1; |
98 | return node.height; |
99 | } |
100 | |
101 | private static long size(Node node) { |
102 | if (node == null) return 0; |
103 | return node.size; |
104 | } |
105 | |
106 | void updateSize() { |
107 | this.size = 1 + size(this.left) + size(this.right); |
108 | } |
109 | |
110 | void updateHeight() { |
111 | this.height = 1 + Math.max(height(this.left), height(this.right)); |
112 | } |
113 | } |
114 | |
115 | private Node rotateRight(Node node) { |
116 | Node tmp = node.left; |
117 | node.left = tmp.right; |
118 | tmp.right = node; |
119 | tmp.size = node.size; |
120 | node.updateSize(); |
121 | node.updateHeight(); |
122 | tmp.updateHeight(); |
123 | return tmp; |
124 | } |
125 | |
126 | private Node rotateLeft(Node node) { |
127 | Node tmp = node.right; |
128 | node.right = tmp.left; |
129 | tmp.left = node; |
130 | tmp.size = node.size; |
131 | node.updateSize(); |
132 | node.updateHeight(); |
133 | tmp.updateHeight(); |
134 | return tmp; |
135 | } |
136 | |
137 | private long balanceFactor(Node node) { |
138 | if(node == null) return 0; |
139 | return Node.height(node.left) - Node.height(node.right); |
140 | } |
141 | |
142 | private Node balance(Node node) { |
143 | if (balanceFactor(node) < -1) { |
144 | if (balanceFactor(node.right) > 0) { |
145 | node.right = rotateRight(node.right); |
146 | } |
147 | node = rotateLeft(node); |
148 | } |
149 | else if (balanceFactor(node) > 1) { |
150 | if (balanceFactor(node.left) < 0) { |
151 | node.left = rotateLeft(node.left); |
152 | } |
153 | node = rotateRight(node); |
154 | } |
155 | return node; |
156 | } |
157 | |
158 | private Node add(Node node, long key) { |
159 | if (node == null) return new Node(key); |
160 | long cmp = key - node.key; |
161 | if (cmp < 0) { |
162 | node.left = add(node.left, key); |
163 | } |
164 | else if (cmp > 0) { |
165 | node.right = add(node.right, key); |
166 | } |
167 | node.updateSize(); |
168 | node.updateHeight(); |
169 | return balance(node); |
170 | } |
171 | |
172 | private Node min(Node node) { |
173 | if (node.left == null) return node; |
174 | return min(node.left); |
175 | } |
176 | |
177 | private Node deleteMin(Node node) { |
178 | if (node.left == null) return node.right; |
179 | node.left = deleteMin(node.left); |
180 | node.updateSize(); |
181 | node.updateHeight(); |
182 | return balance(node); |
183 | } |
184 | |
185 | private Node get(Node x, long key) { |
186 | if (x == null) return null; |
187 | long cmp = key - x.key; |
188 | if (cmp < 0) return get(x.left, key); |
189 | else if (cmp > 0) return get(x.right, key); |
190 | else return x; |
191 | } |
192 | |
193 | public Node get(long key) { |
194 | return get(root, key); |
195 | } |
196 | |
197 | private Node delete(Node node, long key) { |
198 | long cmp = key - node.key; |
199 | if (cmp < 0) node.left = delete(node.left, key); |
200 | else if (cmp > 0) node.right = delete(node.right, key); |
201 | else { |
202 | if (node.left == null) return node.right; |
203 | else if (node.right == null) return node.left; |
204 | else { |
205 | Node y = node; |
206 | node = min(y.right); |
207 | node.right = deleteMin(y.right); |
208 | node.left = y.left; |
209 | } |
210 | } |
211 | node.updateSize(); |
212 | node.updateHeight(); |
213 | return balance(node); |
214 | } |
215 | } |
216 | } |
217 | |
218 | /************************************************************** |
219 | Problem: 1203 |
220 | User: |
221 | Language: Java |
222 | Result: Accepted |
223 | Time:2484 ms |
224 | Memory:180172 kb |
225 | ****************************************************************/ |
Problem F: Pet Adoption [Hard II]
Description
Lanran opened a pet adoption center. Each pet has a characteristic value ($0<p<2^{31}$) and each adopter also hash a value $q$ ($0<q<2^{31}$).
Lanran needs to provide the following services:
- For a pet with characteristic value $p$ arriving, it will be adopted by a person staying in the center whose $q$ is the minimum closest to $p$ or stay in the center if there is no adopter left.
- For an adopter with value $q$ arriving, he/she will choose a pet staying in the center whose $p$ is the minimum closest to $q$ or stay in the center if there is no pet left.
a is the minimum closest to $v$ in set $S$ if and only if:
- for all $a_x∈S$ there is $|a−v|≤|a_x−v|$
- for all $a_i∈S$ and $|a−v|=|a_i−v|$ there is $a≤a_i$
the dissatisfaction for each adoption is defined as $|p−q|$
Input
The first line is a positive integer $n$ ($n≤80000$), which represents the total number of pets and adopters who come to the adoption center. The next n lines describe the pets and adopters who came to the adoption center in the order of arrival. Each line has two positive integers $a$, $b$, where $a=0$ for pets, $a=1$ for adopters, and b for character values.
Output
A positive integer representing the sum of the dissatisfaction of all adopted adopters of pets.
Sample Input
1 | 5 |
2 | 0 2 |
3 | 0 4 |
4 | 1 3 |
5 | 1 2 |
6 | 1 5 |
Sample Output
1 | 3 |
HINT
$|3−2|+|2−4|=3$ and the last adopter has no pets to adopt.
Code
1 |
|
2 | |
3 |
|
4 |
|
5 |
|
6 |
|
7 | |
8 | using namespace std; |
9 | |
10 | typedef long long int lli; |
11 | |
12 | class AVLTree { |
13 | private: |
14 | struct Node { |
15 | lli key, height; |
16 | Node* left, * right; |
17 | explicit Node(lli key) { |
18 | this->key = key; |
19 | this->height = 0; |
20 | this->left = this->right = nullptr; |
21 | } |
22 | |
23 | static lli getHeight(Node* node) { |
24 | if (node == nullptr) return -1; |
25 | return node->height; |
26 | } |
27 | |
28 | void updateHeight() { this->height = 1 + max(getHeight(this->left), getHeight(this->right)); } |
29 | }; |
30 | |
31 | static Node* rotateRight(Node* node) { |
32 | auto tmp = node->left; |
33 | node->left = tmp->right; |
34 | tmp->right = node; |
35 | node->updateHeight(); |
36 | tmp->updateHeight(); |
37 | return tmp; |
38 | } |
39 | |
40 | static Node* rotateLeft(Node* node) { |
41 | auto tmp = node->right; |
42 | node->right = tmp->left; |
43 | tmp->left = node; |
44 | node->updateHeight(); |
45 | tmp->updateHeight(); |
46 | return tmp; |
47 | } |
48 | |
49 | static lli getBalanceFactor(Node* node) { |
50 | if (node == nullptr) return 0; |
51 | return Node::getHeight(node->left) - Node::getHeight(node->right); |
52 | } |
53 | |
54 | static Node* balance(Node* node) { |
55 | if (getBalanceFactor(node) < -1) { |
56 | if (getBalanceFactor(node->right) > 0) node->right = rotateRight(node->right); |
57 | node = rotateLeft(node); |
58 | } |
59 | else if (getBalanceFactor(node) > 1) { |
60 | if (getBalanceFactor(node->left) < 0) node->left = rotateLeft(node->left); |
61 | node = rotateRight(node); |
62 | } |
63 | return node; |
64 | } |
65 | |
66 | static Node* add(Node* node, lli key) { |
67 | if (node == nullptr) return new Node(key); |
68 | lli cmp = key - node->key; |
69 | if (cmp < 0) node->left = add(node->left, key); |
70 | else if (cmp > 0) node->right = add(node->right, key); |
71 | node->updateHeight(); |
72 | return balance(node); |
73 | } |
74 | |
75 | static Node* min(Node* node) { |
76 | if (node->left == nullptr) return node; |
77 | return min(node->left); |
78 | } |
79 | |
80 | static Node* deleteMin(Node* node) { |
81 | if (node->left == nullptr) return node->right; |
82 | node->left = deleteMin(node->left); |
83 | node->updateHeight(); |
84 | return balance(node); |
85 | } |
86 | |
87 | static Node* deleteNode(Node* node, lli key) { |
88 | lli cmp = key - node->key; |
89 | if (cmp < 0) node->left = deleteNode(node->left, key); |
90 | else if (cmp > 0) node->right = deleteNode(node->right, key); |
91 | else { |
92 | if (node->left == nullptr || node->right == nullptr) { |
93 | auto tmp = node->left ? node->left : node->right; |
94 | free(node); |
95 | return tmp; |
96 | } |
97 | else { |
98 | auto tmp = node; |
99 | auto toFree = node; |
100 | node = min(tmp->right); |
101 | node->right = deleteMin(tmp->right); |
102 | node->left = tmp->left; |
103 | free(toFree); |
104 | } |
105 | } |
106 | node->updateHeight(); |
107 | return balance(node); |
108 | } |
109 | |
110 | static Node* find(Node* node, lli key) { |
111 | if (node == nullptr) return node; |
112 | Node* res; |
113 | if (key < node->key) res = find(node->left, key); |
114 | else if (key > node->key) res = find(node->right, key); |
115 | else return node; |
116 | if (res == nullptr) res = node; |
117 | if (res->key == key) return res; |
118 | auto dif = abs(key - res->key) - abs(key - node->key); |
119 | if (dif > 0 || (dif == 0 && node->key < res->key)) res = node; |
120 | return res; |
121 | } |
122 | |
123 | lli size; |
124 | Node* root; |
125 | |
126 | public: |
127 | AVLTree() { |
128 | this->size = 0; |
129 | this->root = nullptr; |
130 | } |
131 | |
132 | lli getSize() { return size; } |
133 | |
134 | void add(lli key) { |
135 | this->size += 1; |
136 | if (this->size == 1) this->root = new Node(key); |
137 | else this->root = AVLTree::add(this->root, key); |
138 | } |
139 | |
140 | void deleteNode(lli key) { |
141 | this->size -= 1; |
142 | this->root = AVLTree::deleteNode(this->root, key); |
143 | } |
144 | |
145 | lli find(lli key) { return AVLTree::find(this->root, key)->key; } |
146 | }; |
147 | |
148 | int main() { |
149 | int n; |
150 | scanf("%i", &n); |
151 | AVLTree pets = AVLTree(); |
152 | AVLTree adopters = AVLTree(); |
153 | AVLTree* wIn, * wOut; |
154 | lli res = 0; |
155 | while (n--) { |
156 | int sig; |
157 | lli flag; |
158 | scanf("%i %lli", &sig, &flag); |
159 | if (sig == 0) { |
160 | wIn = &pets; |
161 | wOut = &adopters; |
162 | } |
163 | else { |
164 | wIn = &adopters; |
165 | wOut = &pets; |
166 | } |
167 | if (wOut->getSize() == 0) wIn->add(flag); |
168 | else { |
169 | auto found = wOut->find(flag); |
170 | res += abs(flag - found); |
171 | wOut->deleteNode(found); |
172 | } |
173 | } |
174 | printf("%lli", res); |
175 | return 0; |
176 | } |
177 | |
178 | /************************************************************** |
179 | Problem: 1200 |
180 | User: |
181 | Language: C++ |
182 | Result: Accepted |
183 | Time:36 ms |
184 | Memory:1216 kb |
185 | ****************************************************************/ |
1 | import java.io.BufferedReader; |
2 | import java.io.IOException; |
3 | import java.io.InputStream; |
4 | import java.io.InputStreamReader; |
5 | import java.util.StringTokenizer; |
6 | import java.util.TreeSet; |
7 | |
8 | public class Main { |
9 | public static void main(String[] args) { |
10 | InputReader input = new InputReader(System.in); |
11 | int n = input.nextInt(); |
12 | TreeSet<Integer> pets = new TreeSet<>(); |
13 | TreeSet<Integer> adopters = new TreeSet<>(); |
14 | TreeSet<Integer> wIn, wOut; |
15 | long res = 0; |
16 | while(n-->0) { |
17 | int sig = input.nextInt(); |
18 | int flag = input.nextInt(); |
19 | if(sig == 0) { |
20 | wIn = pets; |
21 | wOut = adopters; |
22 | } |
23 | else { |
24 | wIn = adopters; |
25 | wOut = pets; |
26 | } |
27 | if(wOut.size() == 0) wIn.add(flag); |
28 | else { |
29 | Integer lower = wOut.lower(flag); |
30 | Integer higher = wOut.higher(flag); |
31 | int found; |
32 | if(lower == null) found = higher; |
33 | else if(higher == null) found = lower; |
34 | else found = (higher - flag) < (flag - lower) ? higher : lower; |
35 | res += Math.abs(flag - found); |
36 | wOut.remove(found); |
37 | } |
38 | } |
39 | System.out.printf("%d", res); |
40 | } |
41 | |
42 | private static class InputReader { |
43 | private BufferedReader reader; |
44 | private StringTokenizer tokenizer; |
45 | |
46 | InputReader(InputStream stream) { |
47 | reader = new BufferedReader(new InputStreamReader(stream), 32768); |
48 | tokenizer = null; |
49 | } |
50 | |
51 | private String next() { |
52 | while(tokenizer == null || !tokenizer.hasMoreTokens()) { |
53 | try { tokenizer = new StringTokenizer(reader.readLine()); } |
54 | catch (IOException e) { throw new RuntimeException(e); } |
55 | } |
56 | return tokenizer.nextToken(); |
57 | } |
58 | |
59 | public int nextInt() { |
60 | return Integer.parseInt(next()); |
61 | } |
62 | } |
63 | } |
64 | |
65 | /************************************************************** |
66 | Problem: 1200 |
67 | User: |
68 | Language: Java |
69 | Result: Accepted |
70 | Time:444 ms |
71 | Memory:45800 kb |
72 | ****************************************************************/ |
Problem G: Gnisrever Pro [Bonus]
Description
Narnal loves reversing and Fibonacci sequence. When he gets an array with length N, he would reverse the array in the intervals determined by Fibonacci sequence for $K$ times.
Let $F_n$ is the n-th Fibonacci number: $F_1=F_2=1$, $F_n=F_{n−1}+F_{n−2}$ for all $n≥3$.
Let $s_n=F_{2n−1} mod N$ and let $t_n=F_{2n} mod N$.
Narnal’s reversing always starts with an array of integers $A=(A[0],…,A[N−1])$ where initially every $A[i]$ is equal to $i$. Now perform $K$ successive operations on $A$, where the $j$-th operation consists of reversing the order of those elements in $A$ with indices between $s_j$ and $t_j$ (both ends inclusive).
Finally, Narnal’s happiness is defined as $R(N,K)=∑^{N−1}_{i=0}i×A[i]$ after $K$ operations.
$1≤N≤10^{18}$, $1≤K≤5×10^5$.
Input
One line gives $N$ and $K$, separated by space.
Output
One line with only $R(N,K) mod 10^9$.
Sample Input
1 | 5 4 |
Sample Output
1 | 27 |
HINT
Consider using nodes to represent the sequences of consecutive numbers.
Using splay tree or other balanced tree data structure!
$R(5,4)=27$ can be seen from the following procedure:
Initial position: (0,1,2,3,4)
Step 1 - Reverse $A[1]$ to $A[1]: (0,1,2,3,4)$
Step 2 - Reverse $A[2]$ to $A[3]: (0,1,3,2,4)$
Step 3 - Reverse $A[0]$ to $A[3]: (2,3,1,0,4)$
Step 4 - Reverse $A[3]$ to $A[1]: (2,0,1,3,4)$
$R(5,4)=0×2+1×0+2×1+3×3+4×4=27$.
Also, $R(10^2,10^2)=246597$.
Lab8_Graph
Problem A: Kingdom
Description
Long time ago, there was a handsome prince named Pisces, who ruled a powerful kingdom. In his kingdom, there were $n$ cities along with $m$ directed roads connecting them. To better govern his kingdom, Pisces had decided to draw an adjacent matrix to represent the circulation relationship among these cities. In his matrix, if there are $a_{ij}$ roads from city $i$ to city $j$, we have $A[i][j]=aij$. Please help him solve this problem.
Input
The first line contains an integer $T$ ($1≤T≤10$), which denotes the number of test cases.
In each test case, the first line contains $2$ integers $n$ ($2≤n≤1000$) and $m$ ($1≤m≤2000$), indicating the number of cities and the number of roads. And in each of the next $m$ lines, there are $2$ integers $u$ and $v$ ($1≤u,v≤n$), representing that there is a directed road from city $u$ to city $v$.
Output
For each test case, print the adjacent matrix.
Sample Input
1 | 2 |
2 | 4 6 |
3 | 1 2 |
4 | 2 3 |
5 | 3 4 |
6 | 2 3 |
7 | 4 2 |
8 | 1 4 |
9 | 3 4 |
10 | 1 2 |
11 | 3 2 |
12 | 1 3 |
13 | 3 1 |
Sample Output
1 | 0 1 0 1 |
2 | 0 0 2 0 |
3 | 0 0 0 1 |
4 | 0 1 0 0 |
5 | 0 1 1 |
6 | 0 0 0 |
7 | 1 1 0 |
Code
1 |
|
2 | |
3 |
|
4 |
|
5 | |
6 | using namespace std; |
7 | |
8 | int main() { |
9 | int testCase; |
10 | scanf("%i", &testCase); |
11 | while(testCase--){ |
12 | int n, m; |
13 | scanf("%i %i", &n, &m); |
14 | vector<vector<int>> kingdom(n + 1, vector<int>(n + 1)); |
15 | while(m--) { |
16 | int u, v; |
17 | scanf("%i %i", &u, &v); |
18 | kingdom[u][v] += 1; |
19 | } |
20 | for(int i = 1; i <= n; i++) { |
21 | for(int j = 1; j <= n; j++) printf("%i ", kingdom[i][j]); |
22 | printf("\n"); |
23 | } |
24 | } |
25 | return 0; |
26 | } |
27 | |
28 | /************************************************************** |
29 | Problem: 1286 |
30 | User: |
31 | Language: C++ |
32 | Result: Accepted |
33 | Time:232 ms |
34 | Memory:5076 kb |
35 | ****************************************************************/ |
Problem B: The Sword of Damocles
Description
One day, an elder told Pisces that there was a legendary sword at the end of the sky - the sword of Damocles. Pisces decided to get the sword at any cost. The area between Pisces and the sword can be described as a rectangular field of $n∗m$ square meters, with Pisces currently at the top left corner and the sword at the bottom right corner. However, $k$ monsters are living in this area, and to keep himself safe, Pisces must keep a distance longer than $S_i$ from the $i$-th monster (Euclidean Distance). Given the locations of these $k$ monsters, Pisces wants to find whether he can get the legendary sword.
Input
The first line of input contains an integer $T$ ($1≤T≤10$), which denotes the number of test cases.
For each of the test case, the first line contains three integers, $N$, $M$, and $K$ ($10≤N,M≤104,1≤K≤1000$). Pisces is now at position $(0,0)$, and the sword at position $(N,M)$. Each of the next $K$ lines describes one of the $K$ monsters, it contains three integers, $X$,$Y$, and $S$ where $(X,Y)$ represents the location and $S$ represents the distance that must be kept. ($0≤X≤N,0≤Y≤M,0<S≤10^4$).
Output
For each test case, print “Yes” if Pisces can get the sword, and “No” otherwise.
Sample Input
1 | 1 |
2 | 10 10 2 |
3 | 3 7 4 |
4 | 5 4 4 |
Sample Output
1 | No |
Code
1 |
|
2 | |
3 |
|
4 |
|
5 |
|
6 |
|
7 | |
8 | using namespace std; |
9 | |
10 | int square(int num); |
11 | int calDistance(vector<int> X, vector<int> Y); |
12 | |
13 | int main() { |
14 | int testCase; |
15 | scanf("%i", &testCase); |
16 | while(testCase--){ |
17 | int swordX, swordY, monsterNum; |
18 | scanf("%i %i %i", &swordX, &swordY, &monsterNum); |
19 | vector<vector<int>> monsters(monsterNum, vector<int>(3)); |
20 | vector<vector<int>> adjacencyList(monsterNum + 2); //monsterNum -> lower bound, +1 upper bound |
21 | for(int i = 0; i < monsterNum; i++) { |
22 | scanf("%i %i %i", &monsters[i][0], &monsters[i][1], &monsters[i][2]); |
23 | if(monsters[i][1] <= monsters[i][2] || swordX - monsters[i][0] <= monsters[i][2]) { |
24 | adjacencyList[monsterNum].push_back(i); |
25 | adjacencyList[i].push_back(monsterNum); |
26 | } |
27 | if(monsters[i][0] <= monsters[i][2] || swordY - monsters[i][1] <= monsters[i][2]) { |
28 | adjacencyList[monsterNum+1].push_back(i); |
29 | adjacencyList[i].push_back(monsterNum + 1); |
30 | } |
31 | } |
32 | for(int i = 0; i < monsterNum; i++) { |
33 | for(int j = i + 1; j < monsterNum; j++) { |
34 | if(j != i) { |
35 | if(calDistance(monsters[i], monsters[j]) <= square(monsters[i][2] + monsters[j][2])) { |
36 | adjacencyList[i].push_back(j); |
37 | adjacencyList[j].push_back(i); |
38 | } |
39 | } |
40 | } |
41 | } |
42 | queue<int> level; |
43 | vector<bool> isSearched(monsterNum + 2); |
44 | isSearched[monsterNum] = true; |
45 | for(auto e : adjacencyList[monsterNum]) { |
46 | isSearched[e] = true; |
47 | level.push(e); |
48 | } |
49 | while(!level.empty()) { |
50 | for(auto i : adjacencyList[level.front()]) { |
51 | if(!isSearched[i]) { |
52 | isSearched[i] = true; |
53 | level.push(i); |
54 | if(i == monsterNum + 1) goto out; |
55 | } |
56 | } |
57 | level.pop(); |
58 | } |
59 | out: |
60 | if(isSearched[monsterNum + 1]) printf("%s\n", "No"); |
61 | else printf("%s\n", "Yes"); |
62 | } |
63 | return 0; |
64 | } |
65 | |
66 | int square(int num) { |
67 | return num * num; |
68 | } |
69 | |
70 | int calDistance(vector<int> X, vector<int> Y) { |
71 | return square(X[0] - Y[0]) + square(X[1] - Y[1]); |
72 | } |
73 | /************************************************************** |
74 | Problem: 1287 |
75 | User: |
76 | Language: C++ |
77 | Result: Accepted |
78 | Time:680 ms |
79 | Memory:1436 kb |
80 | ****************************************************************/ |
Problem C: Valentine’s Day
Description
Today is Valentine’s day, and Pisces is going to date with the beautiful princess in the neighboring kingdom. There are $n$ cities numbered from $1$ to $n$ on the mainland, with Pisces in city $1$ and the princess in city $n$. There are m unidirectional roads among these $n$ cities. Usually, it takes Pisces $1$ unit of time to travel from one city to another, but due to the probable existence of thorns, rivers or even robbers, some of the roads will take $2$ units of time to travel. In other words, the cost of traveling from one city to another is either $1$ unit or $2$ units of time. Pisces wants to know the minimum time that he can meet the princess.
Input
The first line contains $2$ integers $n$ ($2≤n≤2∗10^5$) and $m$ ($1≤m≤4∗10^5$).
In each of the next $m$ lines, there are $3$ integers $u, v$ ($1≤u,v≤n$) and $w$ ($1≤w≤2$), which means there is a road from $u$ to $v$, and it takes $w$ unit(s) of time for Pisces to go through.
Output
Print the minimum time in one line. Or, if he cannot reach the destination, print “-1” (without quotes).
Sample Input
1 | 4 5 |
2 | 1 2 1 |
3 | 2 4 1 |
4 | 2 3 2 |
5 | 3 4 1 |
6 | 1 3 1 |
Sample Output
1 | 2 |
Code
1 |
|
2 | |
3 |
|
4 |
|
5 |
|
6 | |
7 | using namespace std; |
8 | |
9 | int main() { |
10 | int vertices, edges; |
11 | scanf("%i %i", &vertices, &edges); |
12 | vector<vector<int>> cities(vertices + 1); |
13 | while(edges--) { |
14 | int u, v, w; |
15 | scanf("%i %i %i", &u, &v, &w); |
16 | if(w == 2) cities[u].push_back(-v); |
17 | else cities[u].push_back(v); |
18 | } |
19 | auto level = new queue<int>; |
20 | auto tmp = new queue<int>; |
21 | vector<bool> isSearched(vertices + 1); |
22 | isSearched[1] = true; |
23 | level->push(1); |
24 | int time = 1; |
25 | while(!level->empty()) { |
26 | while(!level->empty()) { |
27 | if(level->front() < 0) { |
28 | if(!isSearched[-level->front()]) { |
29 | isSearched[-level->front()] = true; |
30 | if (isSearched[vertices]) goto out; |
31 | tmp->push(-level->front()); |
32 | } |
33 | } |
34 | else { |
35 | for (auto i : cities[level->front()]) { |
36 | if (i < 0) tmp->push(i); |
37 | else { |
38 | if (!isSearched[i]) { |
39 | isSearched[i] = true; |
40 | if (isSearched[vertices]) goto out; |
41 | tmp->push(i); |
42 | } |
43 | } |
44 | } |
45 | } |
46 | level->pop(); |
47 | } |
48 | time += 1; |
49 | auto t = level; |
50 | level = tmp; |
51 | tmp = t; |
52 | } |
53 | out: |
54 | if(isSearched[vertices]) printf("%i", time); |
55 | else printf("%i", -1); |
56 | return 0; |
57 | } |
58 | |
59 | /************************************************************** |
60 | Problem: 1245 |
61 | User: |
62 | Language: C++ |
63 | Result: Accepted |
64 | Time:236 ms |
65 | Memory:14300 kb |
66 | ****************************************************************/ |
Problem D: Defensive Tower
Description
On the mainland, there is a fire-breathing dragon called “lanran”, who is always burning cities and attacking people. So Pisces decides to build some defensive towers in the kingdom to protect his people. A defensive tower is able to protect the city where it is located and the cities adjacent to it. However, building a tower costs a lot, so Pisces could only build at most $⌊n/2$⌋ defensive towers ($n$ is the total number of cities in the kingdom). Please find a way to build defensive towers in order to protect the whole kingdom. If there are multiple answers, print any.
By saying that “two cities are adjacent”, it means that there is one undirected road connecting them.
Input
The first line contains a single integer $t$ ($1≤t≤2∗10^5$), which represents the number of test cases. Then $t$ test cases follow.
In each test case, the first line contains $2$ integers $n$ ($2≤n≤2∗10^5$) and $m$ ($n−1≤m≤min(2∗10^5,\frac{n∗(n−1)}{2})$), indicating the number of cities and the number of roads. And in each of the next $m$ lines, there are $2$ integers $u$ and $v$ ($1≤u,v≤n$) representing the indexes of the cities that this road connects.
There are no self-loops or multiple edges in the given graph. It is guaranteed that the given graph is connected and $∑m≤2∗10^5$.
Output
For each test case print two lines.
In the first line print $k$ — the number of chosen cities.
In the second line print $k$ distinct integers $c_1,c_2,…,c_k$ in any order, where ci is the index of the i-th chosen city.
It is guaranteed that the answer exists. If there are multiple answers, you can print any.
Sample Input
1 | 2 |
2 | 4 6 |
3 | 1 2 |
4 | 1 3 |
5 | 1 4 |
6 | 2 3 |
7 | 2 4 |
8 | 3 4 |
9 | 6 8 |
10 | 2 5 |
11 | 5 4 |
12 | 4 3 |
13 | 4 1 |
14 | 1 3 |
15 | 2 3 |
16 | 2 6 |
17 | 5 6 |
Sample Output
1 | 2 |
2 | 1 3 |
3 | 3 |
4 | 4 3 6 |
Code
1 |
|
2 | |
3 |
|
4 |
|
5 |
|
6 | |
7 | using namespace std; |
8 | |
9 | int main() { |
10 | int testCase; |
11 | scanf("%i", &testCase); |
12 | while(testCase--) { |
13 | int cities, roads; |
14 | scanf("%i %i", &cities, &roads); |
15 | vector<vector<int>> network(cities + 1); |
16 | network[0].push_back(1); |
17 | while(roads--) { |
18 | int u, v; |
19 | scanf("%i %i", &u, &v); |
20 | network[u].push_back(v); |
21 | network[v].push_back(u); |
22 | } |
23 | auto level = new queue<int>; |
24 | auto temp = new queue<int>; |
25 | vector<bool> isSearched(network.size()); |
26 | isSearched[0] = true; |
27 | level->push(0); |
28 | int odd = 0, even = 0; |
29 | auto currentCounter = &odd, tmpCounter = &even; |
30 | while(!level->empty()) { |
31 | while(!level->empty()) { |
32 | for(auto i : network[level->front()]) { |
33 | if(!isSearched[i]) { |
34 | isSearched[i] = true; |
35 | *currentCounter += 1; |
36 | temp->push(i); |
37 | } |
38 | } |
39 | level->pop(); |
40 | } |
41 | auto t0 = level; |
42 | level = temp; |
43 | temp = t0; |
44 | auto t1 = currentCounter; |
45 | currentCounter = tmpCounter; |
46 | tmpCounter = t1; |
47 | } |
48 | auto isOdd = odd <= even; |
49 | if(isOdd) printf("%i\n", odd); |
50 | else printf("%i\n", even); |
51 | int shell = 1; |
52 | isSearched[0] = false; |
53 | level->push(0); |
54 | while(!level->empty()) { |
55 | while(!level->empty()) { |
56 | for(auto i : network[level->front()]) { |
57 | if(isSearched[i]) { |
58 | isSearched[i] = false; |
59 | if(shell & 1) { |
60 | if(isOdd) printf("%i ", i); |
61 | } |
62 | else { |
63 | if(!isOdd) printf("%i ", i); |
64 | } |
65 | temp->push(i); |
66 | } |
67 | } |
68 | level->pop(); |
69 | } |
70 | shell += 1; |
71 | auto t0 = level; |
72 | level = temp; |
73 | temp = t0; |
74 | } |
75 | printf("\n"); |
76 | delete level; |
77 | delete temp; |
78 | } |
79 | return 0; |
80 | } |
81 | |
82 | /************************************************************** |
83 | Problem: 1229 |
84 | User: |
85 | Language: C++ |
86 | Result: Accepted |
87 | Time:768 ms |
88 | Memory:1956 kb |
89 | ****************************************************************/ |
Problem E: Soldiers
Description
Pisces has many soldiers, and he wants to train them in a line. Considering the height, weight and other factors of soldiers, Pisces wants some soldiers to stand in front of others. Besides, if there are multiple orders available, soldiers with smaller indices must stand as in the front as possible. It is guaranteed that the answer exists.
Input
The first line contains an integer $T$ ($1≤T≤10$), which denotes the number of test cases.
For each of the test cases, the first line contains $2$ integers $n$ and $m $ ($2≤n≤2∗10^5,1≤m≤4∗10^5$), which represents the number of soldiers and the number of constrains, respectively. Each of the next $m$ lines contains $2$ integers $u$ and $v$ ($1≤u,v≤n$), which means soldier $u$ must stand in front of soldier $v$.
Output
For each of the test cases, print the order.
Sample Input
1 | 1 |
2 | 6 4 |
3 | 6 5 |
4 | 5 1 |
5 | 4 3 |
6 | 3 2 |
Sample Output
1 | 6 5 1 4 3 2 |
Code
1 |
|
2 | |
3 |
|
4 |
|
5 |
|
6 |
|
7 | |
8 | using namespace std; |
9 | |
10 | const int IN = 0, OUT = 1; |
11 | |
12 | int main() { |
13 | stack<int> output; |
14 | priority_queue<int> priorityQueue; |
15 | |
16 | int testCase; |
17 | scanf("%i", &testCase); |
18 | while(testCase--) { |
19 | int soldiers, constrains; |
20 | scanf("%i %i", &soldiers, &constrains); |
21 | vector<int[2]> degree(soldiers + 1); |
22 | vector<vector<int>> adjacencyList(soldiers + 1); |
23 | while(constrains--) { |
24 | int u, v; |
25 | scanf("%i %i", &u, &v); |
26 | adjacencyList[v].push_back(u); |
27 | degree[u][OUT] += 1; |
28 | degree[v][IN] += 1; |
29 | } |
30 | |
31 | for(int i = 1; i < soldiers + 1; i++) if(degree[i][OUT] == 0) priorityQueue.push(i); |
32 | while(!priorityQueue.empty()) { |
33 | auto top = priorityQueue.top(); |
34 | output.push(top); |
35 | priorityQueue.pop(); |
36 | if(degree[output.top()][IN] != 0) { |
37 | for(auto i : adjacencyList[top]) { |
38 | degree[i][OUT] -= 1; |
39 | if(degree[i][OUT] == 0) priorityQueue.push(i); |
40 | } |
41 | } |
42 | } |
43 | |
44 | degree.clear(); |
45 | adjacencyList.clear(); |
46 | |
47 | while(!output.empty()) { |
48 | printf("%i ", output.top()); |
49 | output.pop(); |
50 | } |
51 | printf("\n"); |
52 | } |
53 | return 0; |
54 | } |
55 | |
56 | /************************************************************** |
57 | Problem: 1288 |
58 | User: |
59 | Language: C++ |
60 | Result: Accepted |
61 | Time:232 ms |
62 | Memory:3388 kb |
63 | ****************************************************************/ |
1 | import java.util.*; |
2 | |
3 | public class Main { |
4 | final static int IN = 0, OUT = 1; |
5 | |
6 | public static void main(String[] args) { |
7 | Scanner input = new Scanner(System.in); |
8 | PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((o1, o2) -> (o2 - o1)); |
9 | Stack<Integer> stack = new Stack<>(); |
10 | |
11 | int testCase = input.nextInt(); |
12 | while(testCase-->0) { |
13 | int soldiers = input.nextInt(); |
14 | int constrains = input.nextInt(); |
15 | int[][] degree = new int[soldiers + 1][2]; |
16 | LinkedList<Integer>[] adjacencyList = new LinkedList[degree.length]; |
17 | for(int i = 1; i < adjacencyList.length; i++) adjacencyList[i] = new LinkedList<>(); |
18 | while(constrains-->0) { |
19 | int u = input.nextInt(); |
20 | int v = input.nextInt(); |
21 | adjacencyList[v].push(u); |
22 | degree[u][OUT] += 1; |
23 | degree[v][IN] += 1; |
24 | } |
25 | |
26 | while(!priorityQueue.isEmpty()) priorityQueue.poll(); |
27 | for(int i = 1; i < degree.length; i++) if(degree[i][OUT] == 0) priorityQueue.offer(i); |
28 | while(!priorityQueue.isEmpty()) { |
29 | int peek = priorityQueue.peek(); |
30 | stack.push(peek); |
31 | priorityQueue.poll(); |
32 | if(degree[peek][IN] != 0) { |
33 | for(int i : adjacencyList[peek]) { |
34 | degree[i][OUT] -= 1; |
35 | if(degree[i][OUT] == 0) priorityQueue.offer(i); |
36 | } |
37 | } |
38 | } |
39 | |
40 | while(!stack.isEmpty()) System.out.printf("%d ", stack.pop()); |
41 | System.out.println(); |
42 | } |
43 | } |
44 | } |
45 | |
46 | /************************************************************** |
47 | Problem: 1288 |
48 | User: |
49 | Language: Java |
50 | Result: Accepted |
51 | Time:2572 ms |
52 | Memory:85164 kb |
53 | ****************************************************************/ |
Problem F: Palace
Description
To celebrate the victory of the war, Pisces has decided to build a splendid palace. The craftsmen has brought back $n$ kinds of cube materials from the dwarf kingdom. The length, width, and height of each material are $a$, $b$ and $c$ respectively. To make the palace magnificent, the craftsmen have to stack these materials together. Material $i$ can be stacked on material $j$ if and only if $a_i<a_j⋂b_i<b_j$, or $a_i<b_j⋂b_i<a_j$. Pisces wants to know how high these materials can stack at most.
Input
The first line contains an integer $T$ ($1≤T≤10$), which denotes the number of test cases.
For each of the test cases, the first line contains an integer $n$ ($1≤n≤2∗10^3$), which represents the number of materials. Each of the next $n$ lines contains $3$ integers $a$, $b$ and $c$ ($1≤a,b,c≤1000$), which represents the size of a material.
Output
For each test case, print the maximum height.
Sample Input
1 | 1 |
2 | 3 |
3 | 2 3 5 |
4 | 4 3 4 |
5 | 3 3 3 |
Sample Output
1 | 9 |
Code
1 |
|
2 | |
3 |
|
4 |
|
5 | |
6 | using namespace std; |
7 | |
8 | int maxHeight(vector<int> &bHeight, vector<vector<int>> &adjacencyList, vector<int[2]> °ree); |
9 | |
10 | int main() { |
11 | int testCase; |
12 | scanf("%i", &testCase); |
13 | while(testCase--) { |
14 | int quantity; |
15 | scanf("%i", &quantity); |
16 | vector<int[2]> bricks(quantity); |
17 | vector<int> bHeight(quantity); |
18 | for(int i = 0; i < quantity; i++) scanf("%i %i %i", &bricks[i][0], &bricks[i][1], &bHeight[i]); |
19 | |
20 | vector<vector<int>> adjacencyList(quantity); |
21 | vector<int[2]> degree(quantity); // 0 --> IN; 1 --> OUT; |
22 | for(int i = 0; i < quantity; i++) { |
23 | for(int j = i + 1; j < quantity; j++) { |
24 | if((bricks[i][0] < bricks[j][0] && bricks[i][1] < bricks[j][1]) || (bricks[i][0] < bricks[j][1] && bricks[i][1] < bricks[j][0])) { |
25 | adjacencyList[i].push_back(j); |
26 | degree[i][1] += 1; |
27 | degree[j][0] += 1; |
28 | } |
29 | else if((bricks[j][0] < bricks[i][0] && bricks[j][1] < bricks[i][1]) || (bricks[j][0] < bricks[i][1] && bricks[j][1] < bricks[i][0])) { |
30 | adjacencyList[j].push_back(i); |
31 | degree[i][0] += 1; |
32 | degree[j][1] += 1; |
33 | } |
34 | } |
35 | } |
36 | bricks.clear(); |
37 | |
38 | printf("%i\n", maxHeight(bHeight, adjacencyList, degree)); |
39 | } |
40 | return 0; |
41 | } |
42 | |
43 | vector<int>* dp; |
44 | vector<int>* bHeightP; |
45 | vector<vector<int>>* adjacencyListP; |
46 | vector<int[2]>* degreeP; |
47 | |
48 | |
49 | int DP(int i) { |
50 | if(dp->at(i) > 0) return dp->at(i); |
51 | if(degreeP->at(i)[1] == 0) { |
52 | dp->at(i) = bHeightP->at(i); |
53 | } |
54 | else { |
55 | for(auto e : adjacencyListP->at(i)) { |
56 | dp->at(i) = max(dp->at(i), DP(e) + bHeightP->at(i)); |
57 | } |
58 | } |
59 | return dp->at(i); |
60 | } |
61 | |
62 | int maxHeight(vector<int> &bHeight, vector<vector<int>> &adjacencyList, vector<int[2]> °ree) { |
63 | bHeightP = &bHeight; |
64 | adjacencyListP = &adjacencyList; |
65 | degreeP = °ree; |
66 | dp = new vector<int>(bHeight.size()); |
67 | int maxH = 0; |
68 | for(int i = 0; i < degree.size(); i++) { |
69 | if(degree[i][0] == 0) { |
70 | DP(i); |
71 | if(dp->at(i) > maxH) maxH = dp->at(i); |
72 | } |
73 | } |
74 | dp->clear(); |
75 | return maxH; |
76 | } |
77 | /************************************************************** |
78 | Problem: 1289 |
79 | User: |
80 | Language: C++ |
81 | Result: Accepted |
82 | Time:696 ms |
83 | Memory:9824 kb |
84 | ****************************************************************/ |
Problem G: Hunting
Description
Pisces likes hunting very much. There are $n$ camps in the forest, with $m$ directed weighted forest roads connecting them. Pisces would choose the path for hunting in accordance to his mood. The length of the path is the sum of the weight $w$ of the roads he has passed. Note that he can pass any road for multiple times.
Now, Pisces wants to know the $k$-th minimum length of all the paths. There are $q$ queries you need to answer.
Input
The first line contains an integer $t$ ($1≤t≤100$), which represents the number of the test cases.
The first line of each test case contains three positive integers $n$, $m$, $q$ ($1≤n,m,q≤5∗10^4$).
Each of the next $m$ lines contains $3$ integers $u$, $v$, $w$, indicating that there is a forest road from $u$ to $v$ and it weights $w$ ($1≤u,v≤n,1≤w≤10^9$).
Each of the next $q$ lines contains one integer $k$ ($1≤k≤5∗10^4$) as mentioned above. It’s guaranteed that $Σn$,$Σm$,$Σq$,$Σmax(k)≤2.5∗10^5$ and $max(k)$ won’t exceed the number of paths in the forest.
Output
For each query, print one integer indicates the answer in line.
Sample Input
1 | 1 |
2 | 2 2 2 |
3 | 1 2 1 |
4 | 2 1 2 |
5 | 3 |
6 | 4 |
Sample Output
1 | 3 |
2 | 3 |
Problem H: Magic
Description
Pisces is learning to build a magic field with a great magician. To build a magic field, Pisces must build some directed channels between $N$ nodes to let the mana flow into it. Unfortunately, Pisces finds that these channels may have some circles, where the mana will get stuck in them forever! To maintain the stability of this magic field, Pisces wants to know whether it is possible to destroy at most one channel to make the magic field acyclic.
Input
The first line contains an integer $T$ ($1≤T≤10$), which denotes the number of test cases.
For each test case, the first line contains $2$ integers $n$ and $m$ ($2 ≤n ≤ 500,1 ≤ m ≤min(n(n − 1), 100000)$) — the number of nodes and the number of channels, respectively. Each of the next $m$ lines contains $2$ integers $u$ and $v$ denoting a directed channel going from node $u$ to node $v$ ($1≤u,v ≤ n,u ≠v$). There is at most one directed channel from $u$ to $v$.
Output
For each test case, print “Yes” (without quotes) if it’s possible, and “No” (without quotes) otherwise.
Sample Input
1 | 1 |
2 | 5 6 |
3 | 1 2 |
4 | 2 3 |
5 | 3 2 |
6 | 3 1 |
7 | 2 1 |
8 | 4 5 |
Sample Output
1 | No |
Problem I: The Elves
Description
To make the kingdom more prosperous, Pisces decides to ally with the elves living in the forest. However, the elven elders want to test Pisces, so they give him a simple question. Given a DAG with n nodes and m edges, the elven elders want to know the value of $∑^n_{i=1}∑^n_{j=1}count(i,j)⋅a_i⋅b_j mod 1e9+7$, where $count(x,y)$ is defined by the number of different paths from $x$ to $y$, and $a$, $b$ are $2$ given arrays. It is too hard for Pisces to answer this question, so he turns to you for help.
Input
The first line contains an integer $T$ ($1≤T≤10$), which denotes the number of test cases.
For each test case, the first line contains $2$ integers $n$ and $m$ ($1 ≤n,m ≤ 10^5$) — the number of nodes and the number of edges, respectively. Each of the next $n$ lines contains $2$ integers $a_i$ and $b_i$. And for the next $m$ lines, each line contains $2$ integers $u$ and $v$ denoting a directed edge going from node $u$ to node $v$ ($1≤u,v ≤ n$).
Output
For each test case, print the answer.
Sample Input
1 | 3 |
2 | 3 3 |
3 | 1 1 |
4 | 1 1 |
5 | 1 1 |
6 | 1 2 |
7 | 1 3 |
8 | 2 3 |
9 | 2 2 |
10 | 1 0 |
11 | 0 2 |
12 | 1 2 |
13 | 1 2 |
14 | 2 1 |
15 | 500000000 0 |
16 | 0 500000000 |
17 | 1 2 |
Sample Output
1 | 4 |
2 | 4 |
3 | 250000014 |
Lab9_Advanced_Graph
Problem A: Traveling
Description
Yuki is a playful girl and she enjoys traveling.
One day, she is planning to play in the Disneyland. The resort is so large that she cannot find the shortest path between two sights immediately, so she wants to ask for your help.
Specifically, there are n sights and m roads in the Disneyland. Each road, with a certain distance, connects two sights. The sights are numbered from 1 to n and the roads are all bidirectional, that is the road from sight u to sight v can be passed from sight v to u. You are asked to find the shortest distance between sight S and sight T.
Input
The first line contains two integers: n and m ($1≤n≤1 000, 1≤m≤5 000$) — the number of sights and roads in Disneyland.
Each of the next m lines contains three space-separated integers: u, v and w ($1≤u, v≤n, 1≤w≤10^5$), meaning that there is a bidirectional road from sight u to sight v with distance w.
The last line contains two integers: S and T ($1≤S, T≤n$) — the origin and destination.
Output
Print the result — the shortest distance between sight S and sight T.
If there are no paths from sight S to sight T, print −1 instead.
Sample Input
1 | 3 3 |
2 | 1 2 5 |
3 | 2 3 5 |
4 | 3 1 2 |
5 | 1 3 |
Sample Output
1 | 2 |
Code
1 |
|
2 | |
3 |
|
4 |
|
5 |
|
6 | |
7 | using namespace std; |
8 | |
9 | auto main() -> int { |
10 | int sights, roads; |
11 | scanf("%i %i", &sights, &roads); |
12 | vector<vector<pair<int,int>>> park(sights + 1); |
13 | while(roads--) { |
14 | int u, v, w; |
15 | scanf("%i %i %i", &u, &v, &w); |
16 | park[u].push_back(make_pair(v, w)); |
17 | park[v].push_back(make_pair(u, w)); |
18 | } |
19 | int sp, ep; |
20 | scanf("%i %i", &sp, &ep); |
21 | vector<int> dist(sights + 1, INT_MAX); |
22 | vector<bool> mark(sights + 1); |
23 | dist[sp] = 0; |
24 | |
25 | for(int c = 1; c < sights;) { |
26 | int minLen = INT_MAX, minIndex = 0; |
27 | for(int i = 1; i < sights; i++) { |
28 | if(!mark[i] && dist[i] < minLen) { |
29 | minLen = dist[i]; |
30 | minIndex = i; |
31 | } |
32 | } |
33 | mark[minIndex] = true; |
34 | c++; |
35 | for(auto e : park[minIndex]) { |
36 | if(!mark[e.first] && dist[minIndex] != INT_MAX && dist[minIndex] + e.second < dist[e.first]) { |
37 | dist[e.first] = dist[minIndex] + e.second; |
38 | } |
39 | } |
40 | } |
41 | |
42 | if(dist[ep] == INT_MAX) printf("%i", -1); |
43 | else printf("%i", dist[ep]); |
44 | return 0; |
45 | } |
46 | |
47 | /************************************************************** |
48 | Problem: 1192 |
49 | User: |
50 | Language: C++ |
51 | Result: Accepted |
52 | Time:60 ms |
53 | Memory:2216 kb |
54 | ****************************************************************/ |
Problem B: Construction
Description
Yuki is a wise girl and she rules a country named Blossom.
Blossom is a big country with n cities, and there are m roads determined to be constructed. Due to many reasons during construction, different roads might have different costs to be built. The roads are bidirectional, that is a road from u to v can be passed from v to u.
Since Yuki wants to make the construction more economical, she decides to choose some of the roads to construct and wants to spend the least money. However, to make the traffic in Blossom convenient, all the cities in Blossom are needed to be connected after construction. Your task is to determine the minimum cost of construction.
Input
The first line contains two integers: n and m ($1≤n≤1 000, 1≤m≤10 000$) — the number of cities and roads to be constructed in Blossom.
Each of the next m lines contains three space-separated integers: u, v and w ($1≤u, v≤n, 1≤w≤10^6$), meaning that there is a bidirectional road from city u to city v considered to be built. And the cost of this edge is w. Cities are numbered from 1 to n.
It is guaranteed that there is at least one plan to connect all cities.
Output
Print one line with an integer — the minimum cost of the construction.
Sample Input
1 | 4 4 |
2 | 1 2 2 |
3 | 2 3 2 |
4 | 3 4 2 |
5 | 4 1 2 |
Sample Output
1 | 6 |
Code
1 |
|
2 | |
3 |
|
4 |
|
5 |
|
6 | |
7 | using namespace std; |
8 | |
9 | struct Edge { |
10 | int a, b, w; |
11 | |
12 | Edge(int a, int b, int w) { |
13 | this->a = a; |
14 | this->b = b; |
15 | this->w = w; |
16 | } |
17 | } *maxEdge = new Edge(-1, -1, INT_MAX); |
18 | |
19 | auto main() -> int { |
20 | int vertexN, edgeN; |
21 | scanf("%i %i", &vertexN, &edgeN); |
22 | vector<char> vertices(vertexN + 1, 0); |
23 | vector<Edge *> edges; |
24 | edges.reserve(edgeN); |
25 | while(edgeN--) { |
26 | int u, v, w; |
27 | scanf("%i %i %i", &u, &v, &w); |
28 | edges.emplace_back(new Edge(u, v, w)); |
29 | } |
30 | |
31 | int length = 0; |
32 | Edge *minEdge = maxEdge; |
33 | for(auto edge : edges) { |
34 | if(edge->w < minEdge->w) minEdge = edge; |
35 | } |
36 | do { |
37 | length += minEdge->w; |
38 | vertices[minEdge->a] = vertices[minEdge->b] = 1; |
39 | minEdge = maxEdge; |
40 | for(auto edge : edges) { |
41 | if(vertices[edge->a] != vertices[edge->b] && edge->w < minEdge->w) minEdge = edge; |
42 | } |
43 | } while(minEdge != maxEdge); |
44 | |
45 | printf("%i\n", length); |
46 | return 0; |
47 | } |
48 | |
49 | /************************************************************** |
50 | Problem: 1193 |
51 | User: |
52 | Language: C++ |
53 | Result: Accepted |
54 | Time:172 ms |
55 | Memory:2360 kb |
56 | ****************************************************************/ |
Problem C: Maze
Description
Yuki is a careless girl and she is designing mazes.
A maze consists of n rooms and m passageways. The rooms are numbered from 1 to n and all the passageways are unidirectional, that is the passageway from room u to v cannot be passed from room v to u. Besides, to avoid tourists being trapped in the maze, all the rooms should be connected, that is for every pair of integers (u,v) such that $1≤u,v≤n,u≠v$, there should be a path from room u to room v.
Yuki has already designed a “maze”. However, due to her carelessness, you need to check whether the maze she designed is a real maze, that is all the rooms in her maze are connected.
Input
The first line contains two integers: n and m ($1≤n,m≤200 000$) —- the number of rooms and passageways in the maze.
Each of the next m lines contains two integers: u and v ($1≤u, v≤n$), meaning that there is a unidirectional passageway from room u to room v.
Output
If all the rooms in the maze are connected, print “Bravo” (without quotation).
Otherwise print “ovarB” (without quotation).
Sample Input
1 | 3 3 |
2 | 1 2 |
3 | 2 3 |
4 | 3 2 |
Sample Output
1 | ovarB |
Code
1 |
|
2 | |
3 |
|
4 |
|
5 |
|
6 | |
7 | using namespace std; |
8 | |
9 | auto main() -> int { |
10 | int vertexN, edgeN; |
11 | scanf("%i %i", &vertexN, &edgeN); |
12 | vector<vector<int>> graph(vertexN + 1); |
13 | vector<vector<int>> graphR(vertexN + 1); |
14 | while(edgeN--) { |
15 | int u, v; |
16 | scanf("%i %i", &u, &v); |
17 | graph[u].push_back(v); |
18 | graphR[v].push_back(u); |
19 | } |
20 | |
21 | vector<int> sequence; |
22 | stack<int> dfsContainer; |
23 | sequence.reserve(vertexN); |
24 | vector<bool> mark(vertexN + 1, true); |
25 | |
26 | dfsContainer.push(1); |
27 | mark[1] = false; |
28 | while(!dfsContainer.empty()) { |
29 | auto top = dfsContainer.top(); |
30 | for(auto vertex : graphR[top]) { |
31 | if(mark[vertex]) { |
32 | dfsContainer.push(vertex); |
33 | mark[vertex] = false; |
34 | break; |
35 | } |
36 | } |
37 | if(dfsContainer.top() == top) { |
38 | sequence.push_back(top); |
39 | dfsContainer.pop(); |
40 | } |
41 | } |
42 | graphR.clear(); |
43 | |
44 | dfsContainer.push(sequence.back()); |
45 | mark[dfsContainer.top()] = true; |
46 | sequence.clear(); |
47 | while(!dfsContainer.empty()) { |
48 | auto top = dfsContainer.top(); |
49 | for(auto v : graph[top]) { |
50 | if(!mark[v]) { |
51 | dfsContainer.push(v); |
52 | mark[v] = true; |
53 | break; |
54 | } |
55 | } |
56 | if(dfsContainer.top() == top) { |
57 | sequence.push_back(top); |
58 | dfsContainer.pop(); |
59 | } |
60 | } |
61 | |
62 | if(sequence.size() == vertexN) printf("Bravo\n"); |
63 | else printf("ovarB\n"); |
64 | return 0; |
65 | } |
66 | |
67 | /************************************************************** |
68 | Problem: 1292 |
69 | User: |
70 | Language: C++ |
71 | Result: Accepted |
72 | Time:116 ms |
73 | Memory:8000 kb |
74 | ****************************************************************/ |
Problem D: Points
Description
Yuki is an ambitious girl and she is addicted to a game called Honor of Kings.
In the game, Yuki is controlling the King to move in a grid of n rows and m columns, where rows are numbered from 1 to n and columns are numbered from 1 to m. The cell at the i-th row and the j-th column is denoted by (i,j). Each cell in the grid contains a point coefficient, denoted by $C_{ij}$.
At first, Yuki can place the King on the grid arbitrarily, that is any cells in the grid can be the initial position for the King. Every turn Yuki can move the King between the cells sharing a common edge. For example, when the King is at (i,j), it can be chosen to move to (i−1,j), (i+1,j), (i,j−1) or (i,j+1), if the destination is not out of the boundary.
Now every time when the King is moved from one cell to an unvisited cell, Yuki will gain the points which is equal to the product of two point coefficients. It means that Yuki will get $C_{xy}⋅C_{ij}$ points when the King moves from (i,j) to (x,y) and visits (x,y) at the first time.
Yuki can stop the game at any time, and she wonders the maximum score she can gain.
Input
The first line contains two integers: n and m ($1≤n,m≤50 000,1≤n⋅m≤50 000$) —- rows and columns of the grid.
Each of the next n lines contains m integers. The j-th number in the i-th line denotes $C_{ij}$ ($1≤C_{ij}≤5 000$).
Output
Print one line with the result — the maximum points.
Sample Input
1 | 1 4 |
2 | 1 2 3 3 |
Sample Output
1 | 17 |
Code
1 |
|
2 | |
3 |
|
4 |
|
5 |
|
6 | |
7 | using namespace std; |
8 | |
9 | int rows, columns; |
10 | |
11 | struct Edge { |
12 | int a, b, w; |
13 | |
14 | Edge(int a, int b, int w) { |
15 | this->a = a; |
16 | this->b = b; |
17 | this->w = w; |
18 | } |
19 | }; |
20 | |
21 | struct Vertex { |
22 | int weight; |
23 | vector<Edge *> adjoin; |
24 | bool mark = false; |
25 | |
26 | Vertex(int row, int column, int weight) { |
27 | this->weight = weight; |
28 | int initSize = 4; |
29 | if(row == 0 || row == rows - 1) { |
30 | if(column == 0 || column == columns - 1) initSize = 2; |
31 | else initSize = 3; |
32 | } |
33 | else if(column == 0 || column == columns - 1) initSize = 3; |
34 | this->adjoin.reserve(initSize); |
35 | } |
36 | }; |
37 | |
38 | struct cmp { |
39 | bool operator()(Edge *a, Edge *b) { |
40 | return a->w < b->w; |
41 | } |
42 | }; |
43 | |
44 | auto main() -> int { |
45 | scanf("%i %i", &rows, &columns); |
46 | vector<Vertex *> cells; |
47 | cells.reserve(rows * columns); |
48 | for(int i = 0, w; i < rows; i++) |
49 | for(int j = 0; j < columns; j++) { |
50 | scanf("%i", &w); |
51 | cells.emplace_back(new Vertex(i, j, w)); |
52 | } |
53 | |
54 | auto maxEdge = new Edge(-1, -1, 0); |
55 | for(int i = 0; i < rows; i++) { |
56 | for(int j = 0; j < columns; j++) { |
57 | int index = i * columns + j; |
58 | if(i + 1 < rows) { |
59 | int down = index + columns; |
60 | int point = cells[index]->weight * cells[down]->weight; |
61 | cells[index]->adjoin.emplace_back(new Edge(index, down, point)); |
62 | cells[down]->adjoin.emplace_back(new Edge(down, index, point)); |
63 | if(point > maxEdge->w) maxEdge = cells[index]->adjoin.back(); |
64 | } |
65 | if(j + 1 < columns) { |
66 | int right = index + 1; |
67 | int point = cells[index]->weight * cells[right]->weight; |
68 | cells[index]->adjoin.emplace_back(new Edge(index, right, point)); |
69 | cells[right]->adjoin.emplace_back(new Edge(right, index, point)); |
70 | if(point > maxEdge->w) maxEdge = cells[index]->adjoin.back(); |
71 | } |
72 | } |
73 | } |
74 | |
75 | vector<int> visited; |
76 | visited.reserve(cells.size()); |
77 | visited.emplace_back(maxEdge->a); |
78 | visited.emplace_back(maxEdge->b); |
79 | cells[maxEdge->a]->mark = true; |
80 | cells[maxEdge->b]->mark = true; |
81 | priority_queue<Edge *, vector<Edge *>, cmp> EdgeQueue; |
82 | for(auto e : cells[visited[0]]->adjoin) if(!cells[e->b]->mark) EdgeQueue.push(e); |
83 | long long int length = maxEdge->w; |
84 | while(visited.size() != cells.size()) { |
85 | for(auto e : cells[visited.back()]->adjoin) if(!cells[e->b]->mark) EdgeQueue.push(e); |
86 | while(cells[maxEdge->b]->mark) { |
87 | maxEdge = EdgeQueue.top(); |
88 | EdgeQueue.pop(); |
89 | } |
90 | cells[maxEdge->b]->mark = true; |
91 | visited.emplace_back(maxEdge->b); |
92 | length += maxEdge->w; |
93 | } |
94 | |
95 | printf("%lli\n", length); |
96 | return 0; |
97 | } |
98 | |
99 | /************************************************************** |
100 | Problem: 1295 |
101 | User: |
102 | Language: C++ |
103 | Result: Accepted |
104 | Time:148 ms |
105 | Memory:14276 kb |
106 | ****************************************************************/ |
Problem E: Portal
Description
Yuki is a magical girl and she has the ability to activate portals.
The country Yuki lives in has n cities and m roads at certain distances. The cities are numbered from 1 to n and all the roads are unidirectional, that is a road from u to v cannot be passed from v to u. Also, there are p portals in the country, each of them connects two cities unidirectional with no distance. Since Yuki doesn’t grasp magic thoroughly, she can activate at most k portals.
Now Yuki is curious about what is the minimum distance between S and T if she activates at most k portals.
Input
The first line contains four integers: n, m, p and k ($1≤n,m,p≤50 000,0≤k≤10$) —- the number of cities, roads, portals and the number of portals Yuki can activate at most.
Each of the next m lines contains three integers: u, v and w ($1≤u, v≤n,1≤w≤1 000 000$), meaning that there is a unidirectional road from city u to city v at distance w.
Each of the next p lines contains two integer: u and v ($1≤u, v≤n$), meaning that there is an inactive portal from city u to city v. Please note that when it is active, Yuki can only be teleported from city u to v unidirectionally.
The last line contains two integers: S and T ($1≤S,T≤n$) —- the origin and destination.
Output
Print one line with the result —- the minimum distance between city S and T.
It is guaranteed that Yuki can move from city S to T by activating at most k portals.
Sample Input
1 | 5 6 3 1 |
2 | 1 3 4 |
3 | 1 2 2 |
4 | 3 5 6 |
5 | 2 4 3 |
6 | 3 4 1 |
7 | 4 5 2 |
8 | 2 3 |
9 | 1 4 |
10 | 1 2 |
11 | 1 5 |
Sample Output
1 | 2 |
Problem F: Boom
Description
Yuki is a grumpy girl and she always wants to make some noise.
One day, Yuki goes to the amusement ground in her university and sets n bombs. The i-th bomb set at the position $(x_i,y_i)$ has exploding radius $r_i$ and lighting-cost $t_i$, which means that Yuki needs to spend $t_i $seconds to config the bomb and make it exploded by remote control.
A bomb will explode instantly if it is in the exploding area (including the boundaries) of any other exploded bombs.
Yuki wants to know the minimum time needed to make all the bombs exploded, and could you give her the answer?
Input
The first line contains an integer n ($1≤n≤1 000$) —- the number of bombs.
In the following n lines, the i-th line contains four integers: $x_i, y_i, r_i$ and $t_i$ ($−10^8≤x_i,y_i≤10^8,0≤r_i,t_i≤10 000$) —- parameters of the bomb.
Output
Print one line with the result —- the minimum time cost.
Sample Input
1 | 5 |
2 | 5 0 1 4 |
3 | 0 0 1 5 |
4 | 1 1 1 6 |
5 | 0 1 1 7 |
6 | 3 0 2 10 |
Sample Output
1 | 15 |
Problem G: NPC
Description
Yuki is a clever girl and she firmly believes that $NP≠P$.
One day TruthBoy, a friend of Yuki, claims that he has found a polynomial-time algorithm to solve Hamiltonian cycle problem, a famous NP-Complete problem.
There is a graph $G=(V,E)$ with n nodes and m edges. Each road is unidirectional, that is an edge from u to v cannot be passed from v to u. Let node 1 be the capital. The path starting at the capital node, visiting every non-capital node exactly once, and finishing in the capital is called a Hamiltonian cycle. And to determine the existence of Hamiltonian cycles in a given graph is called the Hamiltonian cycle problem.
Yuki does not think that TruthBoy has really solved the problem. However, TruthBoy can always give the correct answers to Yuki’s tests. To know the truth, Yuki turns to you for help. Can you help her to find out how TruthBoy solves the problem?
Input
The first line contains two integers: n and m ($2≤n≤100 000, 0≤m≤n+20$) — the number of nodes and directed edges in the graph.
Each of the next m lines contains two integers: u and v ($1≤u, v≤n$), meaning that there is a directional edge from node u to node v.
Nodes are numbered from 1 to n. The capital is numbered as 1.
Output
If there are multiple Hamiltonian cycles, you can print any of them. Print one line with n+1 space-separated integers — a list of nodes along the cycle.
If there is no Hamiltonian cycle, just print “ovarB” (without quotation).
Sample Input
1 | 4 6 |
2 | 1 4 |
3 | 4 1 |
4 | 4 2 |
5 | 2 1 |
6 | 3 4 |
7 | 1 3 |
Sample Output
1 | 1 3 4 2 1 |
HINT
Please remind that your code is judged by a special judge, and any valid answers will be accepted.