本场题目不难,模拟暴力大法好。A~E:模拟+暴力;F:留坑待填;G:埃氏筛+贪心。
A、Restoring Three Numbers
思路:简单数学。
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 = 1e5+5; 27 const int inf = 0x3f3f3f3f; 28 29 30 LL x[5], a, b, c; 31 32 int main() { 33 while(cin >> x[1] >> x[2] >> x[3] >> x[4]) { 34 sort(x + 1, x + 5); 35 b = (x[1] - x[2] + x[3]) / 2; 36 c = x[3] - b; 37 a = x[4] - b - c; 38 cout << a << ' ' << b << ' ' << c << endl; 39 } 40 return 0; 41 }
B、Make Them Equal
思路:暴力+模拟。只需枚举最终的数组变成的数字(1~100)即可。
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 = 105; 27 const int inf = 0x3f3f3f3f; 28 29 30 int n, ans, now, cha, a[maxn]; 31 bool flag; 32 33 int main() { 34 while(~scanf("%d", &n)) { 35 for(int i = 0; i < n; ++i) scanf("%d", &a[i]); 36 sort(a, a + n); 37 ans = inf; 38 for(int j = 0; j <= 100; ++j) { // 枚举最终数组中所有的元素变为j 39 now = 0, cha = 0; // 注意:cha的初始值为0,因为1~n每个数都可能与j相同 40 for(int k = 0; k < n; ++k) // 找到第一个与j不同的数求差的绝对值cha 41 if(a[k] != j) {cha = abs(a[k] - j); break;} 42 for(int k = 0; k < n; ++k) { // 模拟即可 43 if(a[k] < j) { 44 if(a[k] + cha == j) ++now; 45 else break; 46 } 47 else if(a[k] > j) { 48 if(a[k] - cha == j) ++now; 49 else break; 50 } 51 else if(a[k] == j) ++now; 52 } 53 if(now == n) ans = min(ans, cha); 54 } 55 if(ans == inf) puts("-1"); 56 else printf("%d\n", ans); 57 } 58 return 0; 59 }
C、Gourmet Cat
思路:数学+暴力。由题易得一周内猫吃肉的种类依次为 a、b、c、a、c、b、a。若 $ a \geq 3 \land b \geq 2 \land c \geq 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 = 105; 27 const int inf = 0x3f3f3f3f; 28 29 int a, b, c, d, ans, now1, now2, k, dir0[7] = {0, 1, 2, 0, 2, 1, 0}, cnt[3], cnt1[3]; 30 31 int main() { 32 while(cin >> a>> b >> c) { 33 ans = 0; 34 memset(cnt, 0, sizeof(cnt)); 35 if(a >= 3 && b >= 2 && c >= 2) { 36 k = min(a / 3, min(b / 2, c / 2)); 37 a -= 3 * k, b -= 2 * k, c -= 2 * k; 38 ans = 7 * k; 39 } 40 cnt[0] = a, cnt[1] = b, cnt[2] = c, now2 = 0; 41 for(int i = 0; i < 7; ++i) { // 枚举每一天作为起点 42 cnt1[0] = cnt[0], cnt1[1] = cnt[1], cnt1[2] = cnt[2], now1 = 0; 43 for(int j = i; ; ++j) { // 模拟 44 if(cnt1[dir0[j % 7]] > 0) --cnt1[dir0[j % 7]], ++now1; 45 else break; 46 } 47 now2 = max(now1, now2); 48 } 49 cout << ans + now2 << endl; 50 } 51 return 0; 52 }
D、Walking Robot
思路:简单贪心+模拟。详细思路见代码注释。
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 = 2e5+5; 27 const int inf = 0x3f3f3f3f; 28 29 int n, b, a, x, y, ans, s[maxn]; 30 31 int main() { 32 while(cin >> n >> x >> y) { 33 ans = 0; b = x, a = y; 34 for(int i = 0; i < n; ++i) cin >> s[i]; 35 for(int i = 0; i < n; ++i) { 36 if(s[i]) { // 若被光照 37 if(b) { // 先考虑1个b转换成1个a 38 if(a + 1 <= y) --b, ++a, ++ans; // 最大不超过y 39 else if(a) --a, ++ans; // 不能转,则先减去a 40 else if(b) --b, ++ans; // a为0不能继续减,才看b是否剩余 41 else break; 42 } 43 else if(a) --a, ++ans; // 没有b,则只能减去a 44 else break; // 没法减则退出 45 }else { // 没有被光照,不能转 46 if(a) --a, ++ans; // 先考虑a 47 else if(b) --b, ++ans; // a不能减,再考虑b,因为b的作用遇到光时能产生一个a 48 else break; // 没法减则退出 49 } 50 } 51 cout << ans << endl; 52 } 53 return 0; 54 }
E、Two Teams
思路:题意很简单:每次找当前队列中技能最大的学生,向左向右分别连续选择k个学生作为自己的队员。暴力险过。换种思路,用大根堆维护当前序列的最大值,同时标记每个元素分别向前、向后走的第一个位置,暴力模拟即可。
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 = 2e5+5; 27 const int inf = 0x3f3f3f3f; 28 29 int n, k, a, ans[maxn], siz, now, cnt, pos, mp[maxn], lt, rt; 30 vector<int> vec; 31 set<int> stl; 32 set<int>::iterator it; 33 34 int main() { 35 while(~scanf("%d%d", &n, &k)) { 36 memset(ans, 0, sizeof(ans)); 37 memset(mp, 0, sizeof(mp)); 38 vec.clear(); 39 stl.clear(); 40 cnt = 0; 41 for(int i = 0; i < n; ++i) { 42 scanf("%d", &a); 43 vec.push_back(a); 44 mp[a] = i; 45 stl.insert(a); 46 } 47 while((siz = stl.size()) != 0) { 48 it = stl.end(); 49 --it; 50 ++cnt; 51 if(cnt & 1) now = 1; 52 else now = 2; 53 pos = find(vec.begin(), vec.end(), *it) - vec.begin(); 54 lt = max(0, pos - k), rt = min(siz - 1, pos + k); 55 for(int i = lt; i <= rt; ++i) { 56 ans[mp[vec[i]]] = now; 57 stl.erase(vec[i]); 58 } 59 vec.erase(vec.begin() + lt, vec.begin() + rt + 1); 60 } 61 for(int i = 0; i < n; ++i) printf("%d", ans[i]); 62 puts(""); 63 } 64 return 0; 65 }
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 = 2e5+5; 27 const int inf = 0x3f3f3f3f; 28 29 int n, k, a, now1, now2, flag, p1, p2, num, ans[maxn], nex[maxn], per[maxn]; 30 31 priority_queue<pair<int, int> > que; 32 bool vis[maxn]; 33 34 35 int main() { 36 while(~scanf("%d%d", &n, &k)) { 37 while(!que.empty()) que.pop(); 38 memset(ans, 0, sizeof(ans)); 39 memset(per, 0, sizeof(per)); 40 memset(nex, 0, sizeof(nex)); 41 flag = 1; 42 memset(vis, false, sizeof(vis)); 43 for(int i = 1; i <= n; ++i) { 44 scanf("%d", &a); 45 que.push(make_pair(a, i)); 46 per[i] = i - 1; 47 nex[i] = i + 1; 48 } 49 while(!que.empty()) { 50 now1 = que.top().first, now2 = que.top().second, que.pop(); 51 if(vis[now2]) continue; 52 vis[now2] = true; 53 flag = !flag; 54 p1 = per[now2], p2 = nex[now2], ans[now2] = flag + 1; 55 num = k; 56 while(num > 0 && p1 > 0) vis[p1] = true, ans[p1] = flag + 1, --num, p1 = per[p1]; 57 num = k; 58 while(num > 0 && p2 <= n) vis[p2] = true, ans[p2] = flag + 1, --num, p2 = nex[p2]; 59 per[p2] = p1, nex[p1] = p2; 60 } 61 for(int i = 1; i <= n; ++i) printf("%d", ans[i]); 62 puts(""); 63 } 64 return 0; 65 }