2020-06-09 — 习题训练五题解
https://vjudge.net/contest/377554#overview
A - Sum of Odd Integers
题意: 判断是否存在不大于n的k个不同的奇数的和等于n;
思路: k 个奇数和的最小值为k * k, 若 n < k * k 就不存在, 若 n 为奇数 而 k 为偶数, 也不存在, 若 n 为 偶数, k 为奇数 , 也不存在, 剩下的情况就都存在了
#include <iostream> using namespace std; long long t, n, k; int main() { cin >> t; while(t--){ cin >> n >> k; if(k * k > n){ puts("NO"); continue; } if(n % 2 != 0 && k % 2 == 0){ puts("NO"); continue; } if(n % 2 == 0 && k % 2 != 0){ puts("NO"); continue; } puts("YES"); } }
C - EhAb AnD gCd
思路:若该数为偶数,则两个数可以取相同的,若为奇数可以取1 和x - 1;
#include <iostream> using namespace std; int t, x; int main() { cin >> t; while(t--){ cin >> x; if(x % 2 == 0){ cout << x / 2 << " " << x / 2 << '\n'; } else { cout << 1 << " " << x - 1 << '\n'; } } }
D - CopyCopyCopyCopyCopy
思路:由于可以无限拼接,丢尽set里,size()就是最长的上升子序列的长度
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 3e5 + 10; int t; set<int> st; int main() { scanf("%d",&t); while(t--){ int n; scanf("%d", &n); for(int i = 1;i <= n; ++ i){ int x; scanf("%d", & x); st.insert(x); } cout << st.size() << endl; st.clear(); } return 0; }
F - Yet Another Tetris Problem
思路: 倘若有相邻的两个的高度差为奇数的话,就不能消掉
#include <bits/stdc++.h> using namespace std; const int N = 110; int t, n, a[N], b[N]; int main() { cin >> t; while(t--){ cin >> n; int flag = 1; for(int i = 1;i <= n; ++ i){ cin >> a[i]; } for(int i = 2;i <= n; ++ i) if(abs(a[i] - a[i-1]) % 2 != 0){ flag = 0; puts("NO"); break; } if(flag) puts("YES"); } }
G - Yet Another Palindrome Problem
思路: 最短的为三个,所以找到两个下标相差大于二,同时又相等的字符就满足题意,否则不满足
#include <bits/stdc++.h> using namespace std; const int N = 5500; int t, n, a[N], b[N]; int main() { cin >> t; while(t--){ cin >> n; for(int i = 1;i <= n; ++ i) cin >> a[i]; int cnt = 0, flag = 0; for(int i = 1;i <= n - 2; ++ i){ for(int j = i + 2;j <= n; ++ j){ if(a[i] == a[j]){ flag = 1; puts("YES"); break; } } if(flag) break; } if(!flag) puts("NO"); } }
H - Frog Jumps
思路:青蛙的跳跃能力应 >= 最近的两个R 的最大距离(包括起点和终点), 否则青蛙就跳不过去
#include <bits/stdc++.h> using namespace std; const int N = 2e5 + 10; int t, n; char a[N]; int main() { cin >> t; while(t--){ int flag = 0, res = 1; cin >> a; for(int i = 0;i < strlen(a); ++ i) if(a[i] == 'R'){ flag = i + 1, res = max(flag, res); break; } for(int i = flag;i < strlen(a); ++ i) if(a[i] == 'R'){ res = max(i + 1 - flag, res); flag = i + 1; } int k = strlen(a) + 1 - flag; res = max(res, k); cout << res << '\n'; } }
B - Princesses and Princes
看看哪个公主没嫁出去,第一个没嫁出去的给他分配一个对象
#include <iostream> #include <cstdio> #include <map> #include <cstring> using namespace std; const int N = 1e5 + 10; int t, n, cnt; bool SingleDog[N]; int main() { cin >> t; while(t--){ cnt = 0; cin >> n; memset(SingleDog, true, sizeof(SingleDog)); for(int i = 1;i <= n; ++ i){ int m; cin >> m; bool flag = false; for(int j = 0;j < m; ++ j){ int x; cin >> x; if(!flag && SingleDog[x] == true){ SingleDog[x] = false; flag = true; } } if(flag == false && !cnt) cnt = i; } if(!cnt) printf("OPTIMAL\n"); else{ for(int i = 1;i <= n; ++ i) if(SingleDog[i]){ printf("IMPROVE\n%d %d\n", cnt, i); break; } } } return 0; }