[CF]Codeforces Round #527 (Div. 3)
第一次这么晚呀,从晚上十点半开始打,打到凌晨一点回寝,被自己感动到了QAQ
虽然只写了两道水题呵呵哒,要补题,要写DP,要写搜索。
C. Prefixes and Suffixes
Description
Ivan wants to play a game with you. He picked some string ss of length nn consisting only of lowercase Latin letters.
You don't know this string. Ivan has informed you about all its improper prefixes and suffixes (i.e. prefixes and suffixes of lengths from 11 to n−1n−1), but he didn't tell you which strings are prefixes and which are suffixes.
Ivan wants you to guess which of the given 2n−22n−2 strings are prefixes of the given string and which are suffixes. It may be impossible to guess the string Ivan picked (since multiple strings may give the same set of suffixes and prefixes), but Ivan will accept your answer if there is at least one string that is consistent with it. Let the game begin!
Input
The first line of the input contains one integer number nn (2≤n≤1002≤n≤100) — the length of the guessed string ss.
The next 2n−22n−2 lines are contain prefixes and suffixes, one per line. Each of them is the string of length from 11 to n−1n−1 consisting only of lowercase Latin letters. They can be given in arbitrary order.
It is guaranteed that there are exactly 22 strings of each length from 11 to n−1n−1. It is also guaranteed that these strings are prefixes and suffixes of some existing string of length nn.
Output
Print one string of length 2n−22n−2 — the string consisting only of characters 'P' and 'S'. The number of characters 'P' should be equal to the number of characters 'S'. The ii-th character of this string should be 'P' if the ii-th of the input strings is the prefix and 'S' otherwise.
If there are several possible answers, you can print any.
Examples
Input
5
ba
a
abab
a
aba
baba
ab
aba
Output
SPPSPSPS
正确解法:
题目说给你 2*n-2 个字串,其中里面有前缀有后缀,让你从这些字串中找出原子串,其中相同长度的字串都是最起码有两个。再判断每个串到底是前缀还是后缀。(前缀串和后缀串的个数相等都是 n-1个)
其实我不太喜欢串哈哈哈
因为最起码有两个嘛,我就找最长的两个,把这两个拼接成一个原串。
原本我以为,如果出现每个串可以是前缀也可以是后缀随便写就好。于是就wa了两发。
后来我发现,相同长度的串其中必定一个是前缀,另外一个是后缀。
排序判断就好。
但是又wa了。
我发现最长的两个串可以组成两个原串。其中一个可能并不符合要求。
从判断的角度来看这个原串到底符不符合要求。
1 #include "pch.h" 2 #pragma warning(disable:4996) 3 #include<iostream> 4 #include<cstdio> 5 #include<string> 6 #include<cstring> 7 #include<map> 8 #include<set> 9 #include<algorithm> 10 #include<cmath> 11 #include<cstdlib> 12 using namespace std; 13 int n, a, b,bok[300]; 14 string ss, s1; 15 struct student 16 { 17 string s; 18 int len,id; 19 char c; 20 }que[300]; 21 int cmp(student x, student y) 22 { 23 return (x.len < y.len || ((x.len == y.len) && (x.s < y.s))); 24 } 25 bool bijiao(string s1, string s2) 26 { 27 for (int i = 1; i < s1.size(); i++) 28 if (s1[i] != s2[i - 1]) 29 return 0; 30 return 1; 31 } 32 bool qian(string s1, int len) 33 { 34 for (int i = 0; i < len; i++) 35 if (s1[i] != ss[i]) 36 return 0; 37 return 1; 38 } 39 bool hou(string s1, int len) 40 { 41 for (int i = 0; i < len; i++) 42 if (s1[i] != ss[n - len + i]) 43 return 0; 44 return 1; 45 } 46 int main() 47 { 48 scanf("%d", &n); 49 a = 0; b = 0; 50 int flag = 0; 51 for (int i = 1; i <= 2 * n - 2; i++) 52 { 53 cin >> s1; 54 que[i].s = s1; 55 que[i].len = s1.size(); 56 que[i].id = i; 57 if (s1.size() == n - 1) 58 { 59 if (flag == 0) 60 { 61 a = i; 62 flag = 1; 63 } 64 else b = i; 65 } 66 } 67 if (bijiao(que[a].s, que[b].s) == 1) 68 ss = que[a].s + que[b].s[n - 2]; 69 else if (bijiao(que[b].s, que[a].s) == 1) 70 ss = que[b].s + que[a].s[n - 2]; 71 flag = 1; 72 sort(que + 1, que + 2 * n - 2 + 1, cmp); 73 for (int i = 1; i <= 2 * n - 2; i=i+2) 74 { 75 if (qian(que[i].s, que[i].len) && hou(que[i + 1].s, que[i + 1].len)) 76 { 77 bok[que[i].id] = 1; 78 bok[que[i + 1].id] = 2; 79 } 80 else if(qian(que[i+1].s, que[i+1].len) && hou(que[i].s, que[i].len)) 81 { 82 bok[que[i].id] = 2; 83 bok[que[i + 1].id] = 1; 84 } 85 else flag = 0; 86 } 87 if (flag) 88 { 89 for (int i = 1; i <= 2 * n - 2; i++) 90 { 91 if (bok[i] == 1) 92 printf("P"); 93 else printf("S"); 94 } 95 printf("\n"); 96 } 97 else 98 { 99 for (int i = 1; i <= 2 * n - 2; i++) 100 if (que[i].id == a) 101 { 102 a = i; 103 break; 104 } 105 for (int i = 1; i <= 2 * n - 2; i++) 106 if (que[i].id == b) 107 { 108 b = i; 109 break; 110 } 111 ss = que[b].s + que[a].s[n - 2]; 112 for (int i = 1; i <= 2 * n - 2; i = i + 2) 113 { 114 if (qian(que[i].s, que[i].len) && hou(que[i + 1].s, que[i + 1].len)) 115 { 116 bok[que[i].id] = 1; 117 bok[que[i + 1].id] = 2; 118 } 119 else 120 { 121 bok[que[i].id] = 2; 122 bok[que[i + 1].id] = 1; 123 } 124 } 125 for (int i = 1; i <= 2 * n - 2; i++) 126 { 127 if (bok[i] == 1) 128 printf("P"); 129 else printf("S"); 130 } 131 printf("\n"); 132 133 } 134 return 0; 135 }
其实应该先排序,再构成原串的,后来明显就是代码太长了,不够优化,但我又懒。没救了。
看了一个大神的思路跟我一样哈哈哈不过人家60+行。
D1. Great Vova Wall (Version 1)
Description
Vova's family is building the Great Vova Wall (named by Vova himself). Vova's parents, grandparents, grand-grandparents contributed to it. Now it's totally up to Vova to put the finishing touches.
The current state of the wall can be respresented by a sequence aa of nn integers, with aiaibeing the height of the ii-th part of the wall.
Vova can only use 2×12×1 bricks to put in the wall (he has infinite supply of them, however).
Vova can put bricks horizontally on the neighboring parts of the wall of equal height. It means that if for some ii the current height of part ii is the same as for part i+1i+1, then Vova can put a brick there and thus increase both heights by 1. Obviously, Vova can't put bricks in such a way that its parts turn out to be off the borders (to the left of part 11 of the wall or to the right of part nn of it).
The next paragraph is specific to the version 1 of the problem.
Vova can also put bricks vertically. That means increasing height of any part of the wall by 2.
Vova is a perfectionist, so he considers the wall completed when:
- all parts of the wall has the same height;
- the wall has no empty spaces inside it.
Can Vova complete the wall using any amount of bricks (possibly zero)?
Input
The first line contains a single integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of parts in the wall.
The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109) — the initial heights of the parts of the wall.
Output
Print "YES" if Vova can complete the wall using any amount of bricks (possibly zero).
Print "NO" otherwise.
Examples
Input
5
2 1 1 2 5
Output
YES
正确解法:
题目意思是 有一个墙,有n部分,每部分的高度为 ai
现在有 2*1 和 1*2 的砖块去填这个墙,使墙的高度都相同。
我们可以发现:当相邻墙的奇偶性相同时,他们就可以一同变化。
但单独对于一个墙来说,只能使用 2*1 的砖块,于是它的奇偶性就不变。
我们可以通过栈,把元素都放进栈里面,如果相邻且奇偶性相同,就可以删去.
我刚开始的疑惑就是 第一个是偶数,第二第三奇数,第四偶数。
第二第三删去后,第一和第四就相邻了也删去了,这样可以吗?
后来你删去的永远都是2个2个的鸭。完全可以第一和第四分别自己加砖块使他两个相同,然后第二第三一同变化,就可以达到第一和第四一样的高度。
于是2个2个删去之后,如果最后最后只剩下一个元素了。前面一定是偶数对。可以把前面的调到和最后一个相同的情况,就满足条件。
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<map> 6 #include<set> 7 #include<algorithm> 8 #include<cmath> 9 #include<cstdlib> 10 using namespace std; 11 const int maxn = 200000 + 10; 12 int n,a[maxn],que[maxn],cnt=0; 13 int main() 14 { 15 scanf("%d",&n); 16 for (int i = 1; i <= n; i++) 17 { 18 scanf("%d", &a[i]); 19 a[i] = a[i] & 1; 20 } 21 for (int i = 1; i <= n; i++) 22 { 23 que[++cnt] = a[i]; 24 if (cnt >= 2 && que[cnt] == que[cnt - 1]) 25 cnt = cnt - 2; 26 } 27 if (cnt <= 1) printf("YES\n"); 28 else printf("NO\n"); 29 return 0; 30 }
D2. Great Vova Wall (Version 2)
正确解法:
和D1不同的是,现在没有垂直砖了,只有水平砖,于是当你想变化一个墙的时候,必须有与他相邻墙的高度相同,并且一样变化。
D1是找奇偶性,D2就不是这样子了。
我们来思考一个样例:2 1 1 2 5 当这样的时候,就可以
而这样:1 2 2 1 5 就不可以。
第一个中 1 1 可以填充到 2 2,然后与外面的 2 2 在组成两对。而第二个 1 和 2 中间被隔断了。
没有垂直砖之后,墙可以达到的最大高度肯定为初始值的最大值。
因为最大高度为初始值的最大值,于是那些本来就是最大值的墙就可以不变化。
我们还是运用栈的思想, 把整个墙分成一段一段的,两边都是最大值和边界。
当栈里的元素为0时,肯定要放元素,当目前的元素小于栈顶的时候,就可以放进去。当等于栈顶,就可以消去。
大于的时候,直接就不可能了。
我们还是分成一段段的。每一段都要特殊考虑。
啊要我就再设一个最大值数组,找最大值在数组中的位置。
而这个直接用一个循环,边找最大值,边计算。应该是比我优化一点。
1 #include "pch.h" 2 #pragma warning(disable:4996) 3 #include<iostream> 4 #include<cstdio> 5 #include<string> 6 #include<cstring> 7 #include<map> 8 #include<set> 9 #include<algorithm> 10 #include<cmath> 11 #include<cstdlib> 12 using namespace std; 13 const int maxn = 200000 + 10; 14 int n, a[maxn],maxx; 15 int que[maxn], top = 0; 16 int main() 17 { 18 scanf("%d",&n); 19 for (int i = 1; i <= n; i++) 20 { 21 scanf("%d", &a[i]); 22 maxx = max(maxx,a[i]); 23 } 24 for (int i = 1; i <= n; i++) 25 { 26 if (a[i] == maxx) continue; 27 int j = i - 1; 28 while (j + 1 <= n && a[j + 1] != maxx) 29 { 30 j++; 31 if (top != 0 && a[j] == que[top]) 32 top--; 33 else if (top == 0 || a[j] < que[top]) 34 que[++top] = a[j]; 35 else 36 { 37 printf("NO\n"); 38 return 0; 39 } 40 } 41 if (top != 0) 42 { 43 printf("NO\n"); 44 return 0; 45 } 46 i = j; 47 } 48 if(top==0) 49 printf("YES\n"); 50 else printf("NO\n"); 51 return 0; 52 }