Chapter 3 array and string
1
The system sorts out the study notes in Chapter 3. The example code is the code that you try to AC before reading the book method. It is not necessarily better than the standard in the book. Except for the 3-8 Baidu solution, the exercises are completed independently, the website will be reviewed and summarized as appropriate. I hope this blog post can help others easily when you review it in the future. (I suggest you read this blog with zishu-algorithm competition getting started classic (version 2nd ). You are welcome to point out any shortcomings or errors.
2 example 2.1 UVa272 -- Tex Quotes
#include
int main() { bool logo = 1; char ch; while ((ch = getchar()) != EOF) { if (ch == '\"') { if (logo) printf("``"); else printf("''"); logo ^= 1; } else putchar(ch); } return 0;}
9th ~ 10 rows: I used puts to output ''and'', and found that the line break is included, so I used printf's % s output. The LRJ Code uses this technique: q? "''":"''".
Row 3: The variable marked with LRJ is q =! Q is used to implement State transformation. Here I use an exclusive or bitwise operation for higher efficiency.
2.2 UVa10082 -- WERTYU encountered this problem for the first time, and thought it was an abnormal question to be violent with if, and then found the magical use of the constant array. I can't write it if I have read it from another book. Note that the escape character '\' must be written as '\'. The following is the first AC code.
#include
char str[4][50] = {"`1234567890-=", "QWERTYUIOP[]\\", "ASDFGHJKL;'", "ZXCVBNM,./"};int main() { int a[200], i, j; for (i = 0; i < 4; i++) for (j = 1; a[str[i][j]] = str[i][j-1]; j++); a[' '] = ' '; a['\t'] = '\t'; a['\n'] = '\n'; while ((i = getchar()) != EOF) putchar(a[i]); return 0;}
Row 9th: stores the matching values of each input character (str) in an array (a) in a way equivalent to "hash ing ).
Row 11th: in this way, the getchar loop is used to read the I, and the corresponding output is a [I.
After reading the White Book, I found that my approach was somewhat complicated (although more efficient ). Why are there four substrings? It can be combined into one row, and then searched in a loop. After finding the character, output the first character. If the character is not found, the output is as is. This avoids the operation of 10th rows in the original code. However, my method zishu also mentioned later. The following is my optimized code:
#include
char str[200] = {"`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./ \t\t\n\n"};int main() { int a[200], i; for (i = 1; a[str[i]] = str[i-1]; i++); while ((i = getchar()) != EOF) putchar(a[i]); return 0;}
Row 3: note that the space, tab, and carriage return characters at the end are written in two separate lines, so you do not need to write 2nd lines as you did last time.
2.3 UVa401 -- Palindromes, which has been written in a small book for a long time before, is not enough to final code.
#include
#include
char s[100], key1[] = "AEHIJLMOSTUVWXYZ12358", key2[] = "A3HILJMO2TUVMXY51SEZ8", *p;int ispal(){int i = 0, j = strlen(s) - 1;while (i < j) if (s[i++] != s[j--]) return 0;return 1;}int ismir(){int i = -1, j = strlen(s);while (++i <= --j){p = strchr(key1, s[i]);if (p) { if (s[j] != key2[p-key1]) return 0;}else return 0;}return 1;}int main(){int t;while (scanf("%s", s) != EOF){t = ismir();printf("%s -- is ", s);if (ispal()) printf("%s", t?"a mirrored palindrome":"a regular palindrome");else printf("%s", t?"a mirrored string":"not a palindrome");printf(".\n\n");}return 0;}
The key is how to determine the image nature:
Stores the ing relationship between image characters in two character arrays. (Same idea)
I did not consider whether the most intermediate character should also be determined whether to perform horizontal flip for itself, WA several times. (You only need to slightly modify the cycle condition)
Learn strchr functions. (If no character is found for this function, NULL pointer is returned)
LRJ code analysis:
First, the LRJ part of the text string is directly located in main. I don't have to think about it in order to streamline the code, so it is difficult to divide it into two subfunctions. I seem to be short, but the overall thinking is easier to understand.
I use pointers to correspond to the left and right sides and move them to the center. LRJ is indexed by subscript, left is I, right is naturally len-1-i, both methods are OK.
As for his r function, he used the topic to say that there was no blank input. He wrote the rev string and then directly reversed the character for comparison. Because there must be no space in the string, and the characters that are invalid after the reversal are converted into spaces in the LRJ code, they certainly cannot be matched, so the problem can be cleverly solved!
2.4 UVa340 -- Master-Mind Hints: I have done this too, because the number is only 1 ~ 9. You only need to count the number of occurrences of each number, minus the number of strong matches. The idea is the same as that of a book, but it is not so streamlined, so no code will be pasted.
2.5 UVa1583 -- the idea of Digit Generator is the same as that of books.
#include
int y[100100];int main() { for (int i = 0; i < 100000; i++) { int s = i, t = i; while (t) { s+=t%10; t/=10;} if (y[s] == 0) y[s] = i; } int T, pos; scanf("%d", &T); while (T--) { scanf("%d", &pos); printf("%d\n", y[pos]); } return 0;}
2.6 UVa1584 -- Circular Sequence
Question: Enter a length of 2 ~ 100 strings should be understood as loops, and a new string of the same length can be generated from any place as the starting point, asking which of these strings has the smallest Lexicographic Order.
Analysis and Solution: The strcmp function can be used for string comparison. The first addresses of the two strings to be compared, that is, the pointer can be passed in. Then, we can use a min_p value to store the start subscript of the string with the smallest Lexicographic Order, and use I to traverse 1 ~ The starting subscript of the len-1, because it is a ring, so each round of I loop, add the corresponding character at the end of the string y, and add '\ 0' to facilitate the strcmp call.
The method is different from that of zishu. The specific ideas and details, as well as the flexible use of strcmp, can be analyzed and considered by the reader.
#include
#include
int main() { int T; scanf("%d", &T); while (T--) { char y[300]; scanf("%s", y); int len = strlen(y), i, min_p = 0; for (i = 0; i < len; i++) { y[i+len] = y[i]; y[i+len+1] = 0; if (strcmp(y+min_p,y+i+1) > 0) min_p = i+1; } y[min_p+len] = 0; printf("%s\n", y+min_p); } return 0;}
3 exercise 3.1 UVa1585 -- Score
#include
int main() { int T; scanf("%d", &T); while (T--) { char s[100]; scanf("%s", s); int sum = 0, cnt = 0; for (int i = 0; s[i]; i++) { if (s[i]=='X') { sum += cnt*(cnt+1)/2; cnt = 0; } else cnt++; } printf("%d\n", sum+cnt*(cnt+1)/2); } return 0;}
Update every time X is encountered. Otherwise, cnt ++ should pay attention to the last update of row 19th.
After reading this code, refer:
#include
int main() { int T; scanf("%d", &T); while (T--) { char s[100]; scanf("%s", s); int sum = 0, cnt = 0; for (int i = 0; s[i]; i++) { if (s[i]=='X') cnt = 0; else { cnt++; sum += cnt; } } printf("%d\n", sum); } return 0;}
3.2 UVa1586 -- Molar Mass violent each I. If I + 1 is a number, determine whether I + 2 is a number. The number is calculated based on the score. If I + 1 is not a number, the default value is 1. Then judge whether the I-th digit is a letter. If not, continue. Otherwise, accumulate the corresponding quality.
# Include
# Include
Int main () {int T; scanf ("% d", & T); while (T --) {char s [100]; scanf ("% s ", s); double sum = 0, w; for (int I = 0; s [I]; I ++) {// calculate the value of the last two digits if (isdigit (s [I + 1]) {if (isdigit (s [I + 2]) w = 10 * (s [I + 1]-'0') + s [I + 2]-'0 '; else w = s [I + 1]-'0';} else w = 1; // judge the first if (! Isalpha (s [I]) continue; else if (s [I] = 'C') sum ++ = 12.01 * w; else if (s [I] = 'H') sum + = 1.008 * w; else if (s [I] = 'O') sum + = 16.00 * w; else sum ++ = 14.01 * w;} printf ("%. 3lf \ n ", sum);} return 0 ;}
3.3 UVa1225 -- Digit Counting
#include
int main() { int T; scanf("%d", &T); while (T--) { int N, i, t, a[10] = {}; scanf("%d", &N); for (i = 1; i <= N; i++) { t = i; while (t) a[t%10]++, t/=10; } for (i = 0; i < 9; i++) printf("%d ", a[i]); printf("%d\n", a[9]); } return 0;}
Each group can pass through brute force attacks. If you use TLE, you can also create a two-dimensional array a [10000] [10], first obtain the data in a violent round. You only need to create a table.
3.4 UVa455 -- Periodic Strings is used to calculate the cycle of a string. The cycle must be an approximate number of the length. Based on this enumeration, write a function (isThePeriod) to judge whether T is a string's cycle) you can.
The input format is a little pitfall. Each group of tests has an empty row, so I will solve it in the same way as 19th rows.
At last, pay attention to the output format. Each two rows must be separated by an empty line ~~~
#include
#include
int isTthePeriod(char s[], int T) { for (int i = 0; i < T; i++) { for (int j = i+T; j < strlen(s); j+=T) if (s[i] != s[j]) return 0; } return 1;}int main() { int T, kase, len, i; scanf("%d", &T); for (kase = 1; kase <= T; kase++) { char s[100]; while (scanf("%s", s), len = strlen(s), !len); for (i = 1; i <= len; i++) if (len%i == 0 && isTthePeriod(s,i)) break; if (kase != 1) putchar('\n'); printf("%d\n", i); } return 0;}
3.5 UVa227 -- Puzzle is a little troublesome. During the simulation operation, I tried to optimize it. In order to facilitate variable exchange, I used swap of algorithm in C ++, you do not have to write the function yourself.
[Basic framework] |
Defines the 5*5 grid as the global variable s (numbered from 1). The column where the current space is located is x, y |
The output function is used to output the matrix form of s. |
OK is used to operate on the move of a command with ch. the return value 1 indicates that the operation is successful, and the return value 0 indicates that the operation fails. If the switch is successful, update the corresponding x and y and perform the switch operation swap. |
Test is used to complete each group of tests. |
Conclusion: To solve complicated problems, we need to clarify our ideas and divide the big problems into small subproblems.
# Include
# Include using namespace std; int x, y; char s [6] [6]; void output () {for (int I = 1; I <= 5; I ++) {for (int j = 1; j <5; j ++) printf ("% c", s [I] [j]); printf ("% c \ n", s [I] [5]) ;}} int OK (char ch) {switch (ch) {case 'A ': if (x = 1) return 0; else x --; swap (s [x] [y], s [x + 1] [y]); break; case 'B': if (x = 5) return 0; else x ++; swap (s [x] [y], s [x-1] [y]); break; case 'l': if (y = 1) return 0; else y --; Swap (s [x] [y], s [x] [y + 1]); break; case 'r': if (y = 5) return 0; else y ++; swap (s [x] [y], s [x] [Y-1]); break ;}int test () {char ch; int I, j; for (I = 1; I <= 5; I ++) for (j = 1; j <= 5; j ++) if (s [I] [j] = '') x = I, y = j; while (ch = getchar ())! = '0') {if (ch = '\ n') continue; if (! OK (ch) {// invalid operation. You still need to clear the value before '0' while (getchar ()! = '0'); return 0 ;}} return 1 ;}int main () {int kase, I, j; for (kase = 1; kase ++) {gets (& s [1] [1]); if (s [1] [1] = 0) {kase --; continue;} // note that an empty string is read here, to ignore reading continue if (s [1] [1] = 'Z' & s [1] [2] = 0) break; if (kase! = 1) putchar ('\ n'); printf ("Puzzle # % d: \ n", kase); for (I = 2; I <= 5; I ++) gets (& s [I] [1]); if (test () output (); else printf ("This puzzle has no final configuration. \ n ") ;}return 0 ;}
3.6 UVa232-Crossword Answers is the grid that fills in words in middle school English. The start point number is required, and all words are output by row and by column.
#include
#include
int main() { int n, m, a[15][15], k, i, j; char s[15][15]; for (int kase = 1; ; kase++) { if (scanf("%d%d ", &n, &m) != 2) break; k = 0; memset(a, 0, sizeof(a)); memset(s, 0, sizeof(s)); for (i = 1; i <= n; i++) gets(&s[i][1]); for (i = 1; i <= n; i++) for (j = 1; j <= m; j++) { if (s[i][j] == '*') s[i][j] = 0; if (!(s[i-1][j]&&s[i][j-1]) && s[i][j]) a[i][j] = ++k; } if (kase != 1) putchar('\n'); printf("puzzle #%d:\nAcross\n", kase); for (i = 1; i <= n; i++) for (j = 1; j <= m; j++) if (s[i][j] && !s[i][j-1]) printf("%3d.%s\n", a[i][j], s[i]+j); printf("Down\n"); for (i = 1; i <= n; i++) for (j = 1; j <= m; j++) { if (s[i][j] && !s[i-1][j]) { printf("%3d.", a[i][j]); for (k = i; s[k][j]; k++) putchar(s[k][j]); putchar('\n'); } } } return 0;}
3.7 UVa1368 -- DNA Consensus idea: Find the most frequently occurring ACGT characters in each column, that is, the character value of the optimal sequence in this column.
#include
#include
inline int c2d(char c) { if (c == 'A') return 0; else if (c == 'C') return 1; else if (c == 'G') return 2; else return 3;}inline int d2c(int d) { if (d == 0) return 'A'; else if (d == 1) return 'C'; else if (d == 2) return 'G'; else return 'T';}int main() { int T, m, n, i, j, a[1010][4], sum; char s[50][1010]; scanf("%d", &T); while (scanf("%d%d ", &m, &n) == 2) { for (i = 0; i < m; i++) gets(s[i]); memset(a, 0, sizeof(a)); for (i = 0; i < m; i++) for (j = 0; j < n; j++) a[j][ c2d(s[i][j]) ]++; for (sum = j = 0; j < n; j++) { int the_max = a[j][0], id = 0; for (i = 1; i < 4; i++) if (a[j][i]>the_max) id = i, the_max = a[j][i]; putchar(d2c(id)); sum += m - the_max; } printf("\n%d\n", sum); } return 0;}
3.8 UVa202 -- Repeating Decimals this question needs to simulate division. When the same remainder occurs, it indicates the appearance of the cyclic point. Next I will take 5/7 as an example to describe the ideas in detail.
For example, in step 5, the numerator is 5, the denominator is 7 (the denominator remains unchanged throughout the Division), and the quotient of 0th is 0, which indicates that the integer part of the Division is 0 ,, the remainder is 5, multiplied by 10, and 50 is used as the numerator in step 1. the quotient of 1st is 7, which indicates that the first decimal point of the Division is 7, and the remainder is 1, multiplied by 10, take 10 as the numerator in step 2... it can be found that the division of each step is only related to the molecules, that is, when the duplicate values of the molecules appear, for example, when the values of the 1st and 7th steps are both 50, the operation following step 1 is actually repeated between Step 1 and step 2. Therefore, steps 1 to 2 are a circular section. In program implementation, you don't need to store the remainder value. You only need to store the numerator and operator. I defined A [2] [3010], use A [0] [j] to store the molecules in step j, and A [1] [j] to store the operators in step j. Note that the final value can be directly composed of the quotient, such as the red font. The value is 0. 7142857142...
# Include
Int A [2] [3010], p, q; // check whether duplicate molecules exist before I bit; If yes, return the cycle; otherwise, return-1. inline int myfind () {for (p = 1; p <q; p ++) {if (A [0] [p] = A [0] [q]) return q-p;} return-1;} int main () {int kase, a, B, I, len; for (kase = 1; scanf ("% d", & a, & B )! = EOF; kase ++) {A [0] [0] = a; A [1] [0] = a/B; for (q = 1 ;; q ++) {A [0] [q] = (A [0] [q-1]-B * A [1] [q-1]) * 10; A [1] [q] = A [0] [q]/B; len = myfind (); if (len> 0) break ;} printf ("% d/% d = % d. ", a, B, A [1] [0]); for (I = 1; I <p; I ++) printf (" % d ", A [1] [I]); putchar ('); for (I = p; I <q; I ++) {if (I> 50) {printf ("... "); break;} printf (" % d ", A [1] [I]);} printf (") \ n % d = number of digits in repeating cycle \ n ", len );}}
3.9 UVa10340 -- All in All traverses the latter and finds whether the former has corresponding characters.
#include
#include
using namespace std;int fun(string& a, string& b) { int i, j = 0; for (i = 0; i < a.size(); i++, j++) { while (j < b.size() && a[i]!=b[j]) j++; if (j == b.size()) return 0; } return 1;}int main() { string a, b; while (cin >> a >> b) { if (fun(a,b)) cout << "Yes\n"; else cout << "No\n"; }}
3.10 UVa1587 -- Box can answer this question with a bunch of crazy condition branches: http://blog.csdn.net/u013451221/article/details/37672039. However, here I would like to standardize the data and then use C ++ to construct a "Face class" for solving the problem. First, construct a "Face" with a width of w not less than h, and sort it by h as the first level, and w as the second level criterion in ascending order. If a cube can be formed, the side length must be set to a, B, and c in ascending order. After sorting the six input faces, the following distribution must be met:
VczltcSz5NKqzPW8/qGjCjxwcmUgY2xhc3M9 "brush: java;" >#include # include # Include Using namespace std; struct Face {int h, w; void make (int x, int y) {h = min (x, y); w = max (x, y);} bool operator <(const Face & B) const {if (h = B. h) return w <B. w; else return h <B. h;} bool operator = (const Face & B) const {return (h = B. h) & (w = B. w) ;}}; vector A (6); int test1 () {for (int I = 0; I <6; I + = 2) if (! (A [I] = A [I + 1]) return 0; return 1 ;}int test2 () {if (A [0]. h = A [2]. h & A [0]. w = A [4]. h & A [2]. w = A [4]. w) return 1; else return 0;} int main () {int x, y; while (cin> x> y) {A [0]. make (x, y); for (int I = 1; I <6; I ++) {cin> x> y; A [I]. make (x, y);} sort (. begin (),. end (); if (test1 () & test2 () cout <"POSSIBLE \ n"; else cout <"IMPOSSIBLE \ n";} return 0 ;}
3.11 UVa1588 -- Kickdown assume that s1 is the fixed device, so as long as s2 is aligned with the left end of s1 in the initial state (this state is marked by Offset k = 0 ), then, when the value of k is 0, the two devices will not "the sum of each bit will not exceed 3". If not, the devices will be able to perform the test at the offset to the right. You can know that there is a k that can make it true (that is, when the left side of s2 is connected to the right side of s1 ). In this way, the first feasible solution is the optimal solution. However, the above discussion also omitted a combination, that is, s2 can be shifted to the left. In fact, the above solution is written as a fun function for encapsulation. As long as the external (main function) cleverly utilizes symmetry, it can reuse the previous code.
#include
#include
#include using namespace std;int len1, len2;char s1[110], s2[110];int test(int k, char s1[], char s2[]) { for (int i = 0; s1[k+i] && s2[i]; i++) if (s1[k+i]+s2[i]-2*'0' > 3) return 0; return 1;}int fun(char s1[], char s2[]) { int k = 0; while (!test(k,s1,s2)) k++; return max(strlen(s1), strlen(s2)+k);}int main() { while (scanf("%s%s", s1, s2) != EOF) { printf("%d\n", min(fun(s1,s2), fun(s2,s1))); } return 0;}
3.12 UVa11809 -- Floating-Point Numbers first needs to know the principle of binary decimal places:
The idea of this question is to first calculate all the values corresponding to M and E as matrix C, where C [M, E] = the maximum value corresponding to the ending M and order code E. Then, for the input AeB, find the Row M and column E with the same value in C, which is the answer. However, there are two key points. First, the value is too large to reach 2 ^ (2 ^ 30-1), far beyond the storage range of double. Therefore, we may wish to make a transformation to the value, and store the base-10 logarithm value. Second, the error between the tail error in the calculation process and the error of the double will cause the Accuracy Problem. Therefore, in matrix C, we can find the matching point closest to the input value, that is, the absolute value of the difference is the smallest.
Finally, there are some special points M = 0, E = 1. in the program, the error 0.0-0.0 <0.0 condition is no, causing the pi and pj to fail to be updated, this problem can be solved by initializing pi and pi to 0 and 1 respectively.
# Include
# Include
# Include
Double C [10] [31]; void init () {int I, j, v; double f [10] ={ 0.5}, g [31], t; for (I = 1, t = 0.5; I <10; I ++) {f [I] = f [I-1] + t/2; t/= 2 ;} for (I = 0; I <10; I ++) f [I] = log10 (f [I]); for (I = 1, v = 2; I <= 30; I ++) {g [I] = (v-1.0) * log10 (2.0); v <= 1 ;}for (I = 0; I <10; I ++) for (j = 1; j <= 30; j ++) C [I] [j] = f [I] + g [j];} int main () {int I, j; char s [100], * p; double A, B; init (); while (scanf ("% s", s), strcmp (s, "0e0") {p = strchr (s, 'E'); * p = 0; // change the location of 'E' to '\ 0' sscanf (s, "% lf", & ); sscanf (p + 1, "% lf", & B); int pi = 0, pj = 1; B = A = log10 (A) + B; // next A stores the expression value, and B records the difference value for (I = 0; I <10; I ++) for (j = 1; j <= 30; j ++) if (fabs (A-C [I] [j]) <B) pi = I, pj = j, B = fabs (A-C [I] [j]); printf ("% d \ n", pi, pj);} return 0 ;}