A. Yet Another Tetris Problem
易证 , 对于任意给定的初始摆放方式,都可以通过添加2*1的新方格来调整每一纵列间的相对高度,使得各个纵列间的高度差不超过1。
当所有的纵列被消除不超过1格高时,如果有部分高度为1,有部分高度为0,那么表明无法全部消除。
故在一开始读入数据时,求出最大高度,然后用这个最大高度与其余所有的高度做差,如果差为偶数,则这一列可消除。如果差为奇数,则表明无法消除。
1 #include <iostream> 2 #include <cstdio> 3 #define Maxsize 100+10 4 #define MAX(a,b) (a>b?a:b) 5 using namespace std; 6 int arr[Maxsize]; 7 int main(){ 8 int t; 9 cin >> t; 10 while (t--) { 11 int n,peek = 0; 12 int flag = 1; 13 cin >> n; 14 for (int i = 1; i <= n; i++) { 15 cin >> arr[i]; 16 peek = MAX(peek,arr[i]); 17 } 18 for (int i = 1; i <= n; i++) { 19 if((peek - arr[i])%2){ 20 flag = 0; 21 break; 22 } 23 } 24 if(flag) 25 cout << "YES" << endl; 26 else 27 cout << "NO" << endl; 28 } 29 return 0; 30 }
B. Yet Another Palindrome Problem
只需要找到一对相同的数,且不相邻即可。
1 #include <iostream> 2 #include <vector> 3 #define Maxsize 5000+1 4 using namespace std; 5 int book[Maxsize]; 6 int ptr[Maxsize]; 7 int main(){ 8 int t; 9 cin >> t; // 100 10 while (t--) { 11 int n; 12 int flag = 0; 13 cin >> n; // 3 - 5000 , ai 1 - n sum n5000 14 for (int i = 1; i <= n; i++) { 15 cin >> book[i]; 16 ptr[book[i]] = 0; 17 } 18 for (int i = 1; i <= n; i++) { 19 if (ptr[book[i]] == 0) { 20 ptr[book[i]] = i; 21 }else { 22 if (i - ptr[book[i]] > 1) { 23 flag = 1; 24 break; 25 } 26 } 27 } 28 if (flag) { 29 cout << "YES"; 30 }else { 31 cout << "NO"; 32 } 33 cout << endl; 34 } 35 return 0; 36 }
C. Frog Jumps
以这个题为例 , 如果想要从起点跳到终点,最大答案就是一步跳完, ans = dest - src
如果想要缩小答案,必须要依靠中转点。假设距离dest最近的中转点为 P
显然,P点必定是 ‘ R ’ (如果是 L, 那么青蛙不可能从P跳到dest)
因此,青蛙只需要先想办法从 src 跳到 P, 再从 P 跳到 dest
因此, ans( src -> dest ) = max( ans( src -> P ) , ans( P -> dest ) )
其中,我们可以直接求出 ans( P -> dest ) = 4。
到这里,我们已经将原问题转化成了一个规模小的子问题。
我们递归的重复进行过程,可以求出,最终的答案为
ans = max( x1, x2 , ... , xn ) + 1
其中每一个 xi 为由 src 到达 dest 中的一段连续的 L 长度。
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #define MAX(a,b) (a>b?a:b) 5 #define Maxsize 200000+10 6 using namespace std; 7 char book[Maxsize]; 8 int main(){ 9 int t; 10 scanf("%d",&t); 11 while (t--) { 12 scanf("%s",book); 13 int len = (int)strlen(book); 14 book[len] = 'R'; // 终点担任哨兵的作用 15 len++; 16 int ans = 1; 17 int find_max = 0; 18 int cnt = 0; 19 for (int i = 0; i < len; i++) { 20 if(book[i]=='R'){ 21 find_max = MAX(find_max,cnt); 22 cnt = 0; 23 }else 24 cnt++; 25 } 26 printf("%d\n",ans+find_max); 27 } 28 return 0; 29 }
D. Pair of Topics
首先将题目给的等式变形,设ci = ai-bi , 等式化为 ci + cj > 0 -> cj > ci -> cj >= -ci+1
将数组排序(虽然会破坏顺序,但是最终答案不会改变),然后二分查找第一个 >= -ci + 1的下标。
注意ans要开 long long,不然会爆int 会WA 第12个点 ?
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #define Maxsize 200000+1 5 using namespace std; 6 typedef long long ll; 7 inline int read(){ 8 int x = 0; 9 char c = getchar(); 10 while (c<'0'||c>'9') { 11 c = getchar(); 12 } 13 while (c>='0'&&c<='9') { 14 x = (x<<1)+(x<<3)+(c^48); 15 c = getchar(); 16 } 17 return x; 18 } 19 inline int bsch(int val,int head,int tail,int arr[]) { // 二分查找 , 得到第一个大于等于 x 的值的下标 20 if (head > tail) { 21 return -1; 22 } 23 while (head < tail) { 24 int mid = (head+tail) >> 1; 25 if (arr[mid] < val) { 26 head = mid+1; 27 }else if(arr[mid] >= val) { 28 tail = mid; 29 } 30 } 31 if(arr[head] >= val) 32 return head; 33 else return -1; 34 } 35 int arr[Maxsize]; 36 int main(){ 37 int n = read(); 38 for (int i = 1; i <= n; i++) { 39 arr[i] = read(); 40 } 41 for (int i = 1; i <= n; i++) { 42 arr[i] -= read(); 43 } 44 sort(arr+1,arr+1+n); // 默认小到大 45 ll ans = 0; 46 for (int i = 1; i <= n; i++) { 47 int x = bsch(-arr[i]+1,i+1,n,arr); 48 if (x != -1) { 49 ans += n - x + 1; 50 } 51 } 52 cout << ans; 53 return 0; 54 }