Codeforces Round #662 (Div. 2)
A. Rainbow Dash, Fluttershy and Chess Coloring (CF 1393 A)
题目大意
给定一个的棋盘,要黑白间隔涂色。每次只能选择一些格子涂色,这些格子必须与某些已经涂色的格子相邻,问最小涂色次数。初始时最外围的一圈都可以涂色。
解题思路
开始看样例有种输出n-1的冲动
想象一下涂色情况可知,第一次涂最外围一圈的白色,第二次涂最外围的黑色和第二外围的黑色,第三次涂第二外围的白色和第三外围的白色……
若n是偶数,则最后是涂一个四个格子的两个颜色,然后还要一次涂另一个颜色,次数是
若n是奇数,最后一次则是涂一个格子,次数是
综上,答案就是(整除)。
神奇的代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int kase; cin>>kase; for (int ii = 1; ii <= kase; ii++) { int n; cin>>n; cout<<(n/2+1)<<endl; } return 0; }
B. Applejack and Storages (CF 1393 B)
题目大意
初始有块木板,并已知每块木板的长度。现有次操作,每次操作会增加或者移除已有的长度为x的木板,问,每次操作后,是否能从这些木板中选出一些木板来,作出一个矩形和一个正方形。(正方形也是特殊的矩形)
解题思路
统计一下同一长度4个4个的有多少份,2个2个的有多少份,判断就可以了。
神奇的代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } const int N = 1e5+8; int n,q,l; int cnt[N]; multiset<int> two,four; char s[5]; int main(void) { read(n); for(int u,i = 1; i <= n; ++ i){ read(u); if (cnt[u] % 4 == 3){ four.insert(u); } if (cnt[u] % 2 == 1){ two.insert(u); } cnt[u]++; } read(q); while(q--){ scanf("%s",s); read(l); if (s[0] == '+'){ if (cnt[l] % 4 == 3){ four.insert(l); } if (cnt[l] % 2 == 1){ two.insert(l); } cnt[l]++; }else{ if (cnt[l] % 4 == 0){ four.erase(four.find(l)); } if (cnt[l] % 2 == 0){ two.erase(two.find(l)); } cnt[l]--; } if (four.size() >= 2) puts("YES"); else if (four.size() == 0) puts("NO"); else if (two.size() >=4) puts("YES"); else puts("NO"); } return 0; }
C. Pinkie Pie Eats Patty-cakes (CF 1393 C)
题目大意
给定个数字,要求重新排列这n个数字,使得同一个数字之间的距离的最小值最大。两个相同数的距离即这两个数之间的数字个数。
解题思路
很显然出现次数最多的数字是决定答案的关键。设数字中出现最多的次数为ma次,我们将这ma个数字作为隔板,隔板之间能够放的最多的数字即为,至于余数可以放到最后一个隔板的右边,总存在一种方式,其他数字的最小距离不会大于隔板间的数量。
但如果出现次数为ma次的数字不止一个,而是有cnt个,我们就可以把这cnt个捆绑在一起,即一个长度为cnt的隔板。
所以最终答案即为
神奇的代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } int main(void) { int kase; read(kase); for (int ii = 1; ii <= kase; ii++) { int n; read(n); vector<int> tot(n+1); int ma = 0; int cnt = 0; for(int a, i = 1; i <= n; ++ i){ read(a); tot[a]++; if (ma < tot[a]){ ma = tot[a]; cnt = 1; }else if (ma == tot[a]) ++cnt; } int ans = (n - ma * cnt) / (ma - 1) + cnt - 1; write(ans,'\n'); } return 0; }
D. Rarity and New Dress (CF 1393 D)
题目大意
给定一张网格图,问由相同字母组成的菱形个数有多少。一个格子也算是一个菱形。
解题思路
一个菱形有一个所谓的中心,从数据范围来看我们自然不能从中心BFS来得到它能拓展多少。
我们把菱形拆成中心所在的一条线,上三角形和下三角形。
我们设表示以为中心的上三角形的长度(值为左或右拓展的距离),为下三角形,为从向左拓展的距离,为向右拓展的距离,则点所形成的最大菱形即为
转移
还有一个不太理解的,是设表示以为底部点,最大拓展的长度。(1,1)是左上角。
而对于以为底部点的菱形,可以看做是以为底部点的菱形往下边拓展一格,或者以为底部点的菱形往右边拓展一格,或者以为底部点的菱形往左边拓展一格。由于往右边或往右边拓展一格时,顶部的格子会往上拓展一个,此时又有的限制?
至于会取,如果字母相同的话,否则
神奇的代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } const int N = 2e3+8; char s[N][N]; LL up[N][N],down[N][N],l[N][N],r[N][N]; LL ans; int n,m; int main(void) { read(n); read(m); for(int i = 0; i < n; ++ i){ scanf("%s",s[i]); } for(int i = 0; i < n; ++ i){ for(int sign=0,cnt=1,j = 0; j < m; ++ j){ if (s[i][j] != sign){ sign = s[i][j]; cnt = 0; } ++cnt; l[i][j] = cnt; up[i][j] = down[i][j] = 1; } for(int sign=0,cnt=1,j = m-1; j >= 0; -- j){ if (s[i][j] != sign){ sign = s[i][j]; cnt = 0; } ++cnt; r[i][j] = cnt; } } for(int i = 1; i < n; ++ i){ for(int j = 0; j < m; ++ j){ if (s[i][j] == s[i-1][j]){ up[i][j] = min(up[i-1][j] + 1, min(l[i][j], r[i][j])); } } } for(int i = n-1; i >= 0; -- i){ for(int j = 0; j < m; ++ j){ if (s[i][j] == s[i+1][j]){ down[i][j] = min(down[i+1][j] + 1, min(l[i][j], r[i][j])); } } } for(int i = 0; i < n; ++ i) for(int j = 0; j < m; ++ j) ans += min(up[i][j],down[i][j]); write(ans,'\n'); return 0; }
本文作者:~Lanly~
本文链接:https://www.cnblogs.com/Lanly/p/13460553.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步