Codeforces Global Round 2
A、Ilya and a Colorful Walk
思路:简单贪心。为了使得不相等的2个元素所在位置之间的距离最大,只需固定首尾元素分别扫一遍即可。
AC代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <iostream> 6 #include <algorithm> 7 #include <iomanip> 8 #include <complex> 9 #include <string> 10 #include <vector> 11 #include <set> 12 #include <map> 13 #include <list> 14 #include <deque> 15 #include <queue> 16 #include <stack> 17 #include <bitset> 18 using namespace std; 19 typedef long long LL; 20 typedef unsigned long long ULL; 21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左 22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向 23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2}; 24 const double eps = 1e-6; 25 const double PI = acos(-1.0); 26 const int maxn = 300005; 27 const int inf = 0x3f3f3f3f; 28 29 int n, lt, rt, c[maxn]; 30 31 32 int main() { 33 while(cin >> n) { 34 lt = 0, rt = n - 1; 35 for(int i = 0; i < n; ++i) cin >> c[i]; 36 while(lt < n && c[lt] == c[n - 1]) ++lt; 37 while(rt > 0 && c[0] == c[rt]) --rt; 38 cout << max(n - 1 - lt, rt) << endl; 39 } 40 return 0; 41 }
B、Alyona and a Narrow Fridge
思路:贪心+暴力。题意就是有一个高为h宽为2的冰箱,给定n个瓶子的高度$ a _i $(宽为1),要求从左往右依次往冰箱里放瓶子,问最多能放几个。由于数据较小,直接双重循环暴力+排序。做法:从左往右枚举每一个瓶子i,先将1~i这i个瓶子的高度进行排序,然后从后往前贪心,先放高度高的,最后能放高度小的个数就多一点,若刚好能放i个,那就继续以这种策略执行下去,否则不满足题意,直接break。
AC代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <iostream> 6 #include <algorithm> 7 #include <iomanip> 8 #include <complex> 9 #include <string> 10 #include <vector> 11 #include <set> 12 #include <map> 13 #include <list> 14 #include <deque> 15 #include <queue> 16 #include <stack> 17 #include <bitset> 18 using namespace std; 19 typedef long long LL; 20 typedef unsigned long long ULL; 21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左 22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向 23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2}; 24 const double eps = 1e-6; 25 const double PI = acos(-1.0); 26 const int maxn = 1005; 27 const int inf = 0x3f3f3f3f; 28 29 int n, h, ans, now, a[maxn], b[maxn], cnt; 30 31 int main() { 32 while(cin >> n >> h) { 33 ans = 0; 34 for(int i = 0; i < n; ++i) cin >> a[i]; 35 for(int i = 0; i < n; ++i) { 36 b[i] = a[i]; now = h, cnt = 0; 37 sort(b, b + i + 1); 38 for(int j = i; j >= 0; --j) { 39 if(now >= b[j]) { 40 cnt += 2; 41 if(j == 0) --cnt; 42 now -= b[j]; 43 --j; 44 } 45 } 46 if(cnt != i + 1) break; 47 else ans = i + 1; 48 } 49 cout << ans << endl; 50 } 51 return 0; 52 }
C、Ramesses and Corner Inversion
思路:思维。每次操作至少为 $ 2 \times 2 $ 大小的规则矩形。通过样例不难发现,每次反转该矩形的四个角元素之后,这4个元素所在的行和列各自的奇偶性不变。也就是说,若矩阵A每行、每列的奇偶性和矩阵B每行、每列的奇偶性相同,那么矩阵A就能变换成矩阵B,否则为"No"。
AC代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <iostream> 6 #include <algorithm> 7 #include <iomanip> 8 #include <complex> 9 #include <string> 10 #include <vector> 11 #include <set> 12 #include <map> 13 #include <list> 14 #include <deque> 15 #include <queue> 16 #include <stack> 17 #include <bitset> 18 using namespace std; 19 typedef long long LL; 20 typedef unsigned long long ULL; 21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左 22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向 23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2}; 24 const double eps = 1e-6; 25 const double PI = acos(-1.0); 26 const int maxn = 505; 27 const int inf = 0x3f3f3f3f; 28 29 int n, m, A[maxn][maxn], B[maxn][maxn], cnt1_r[maxn], cnt1_c[maxn], cnt2_r[maxn], cnt2_c[maxn]; 30 bool flag; 31 32 33 int main() { 34 while(cin >> n >> m) { 35 memset(cnt1_r, 0, sizeof(cnt1_r)); 36 memset(cnt1_c, 0, sizeof(cnt1_c)); 37 memset(cnt2_r, 0, sizeof(cnt2_r)); 38 memset(cnt2_c, 0, sizeof(cnt2_c)); 39 flag = false; 40 for(int i = 0; i < n; ++i) { 41 for(int j = 0; j < m; ++j) { 42 cin >> A[i][j]; 43 cnt1_r[i] += A[i][j]; 44 cnt1_c[j] += A[i][j]; 45 } 46 } 47 for(int i = 0; i < n; ++i) { 48 for(int j = 0; j < m; ++j) { 49 cin >> B[i][j]; 50 cnt2_r[i] += B[i][j]; 51 cnt2_c[j] += B[i][j]; 52 } 53 } 54 for(int i = 0; i < n && !flag; ++i) 55 if(cnt1_r[i] % 2 != cnt2_r[i] % 2) flag = true; 56 for(int j = 0; j < m && !flag; ++j) 57 if(cnt1_c[j] % 2 != cnt2_c[j] % 2) flag = true; 58 puts(flag ? "No" : "Yes"); 59 } 60 return 0; 61 }