Advertisement
Dmaxiya

P11724 [JOIG 2025] ポスター 2 / Poster 2

Feb 23rd, 2025
181
0
364 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.68 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <map>
  4. #include <cstdio>
  5. #define x first
  6. #define y second
  7. #define PII pair<int, int>
  8. using namespace std;
  9. typedef long long LL;
  10.  
  11. int n, k, g[300][300], maxn, max_x, max_y, minn, color, cnt, ans;
  12. map<int, int> mp1, mp3;
  13. map<PII, int> mp2;
  14. int dx[] = {0, 0, 1, 1};
  15. int dy[] = {0, 1, 0, 1};
  16.  
  17. bool in(int x, int y) {
  18.     return x >= 1 && x <= n && y >= 1 && y <= n;
  19. }
  20.  
  21. int main() {
  22. #ifdef ExRoc
  23.     freopen("test.txt", "r", stdin);
  24. #endif // JiuQi
  25.  
  26.     scanf("%d %d", &n, &k);
  27.     for (int i = 1; i <= n; ++i) {
  28.         for (int j = 1; j <= n; ++j) {
  29.             scanf("%d", &g[i][j]);
  30.         }
  31.     }
  32.     //判断要修改哪一个格子
  33.     for (int i = 1; i <= n - 1; ++i) {
  34.         for (int j = 1; j <= n - 1; ++j) {
  35.             mp1.clear(); // 将mp1清空,方便下一次四个格子中颜色的记录
  36.             for (int r = 0; r < 4; ++r) {
  37.                 mp1[g[i + dx[r]][j + dy[r]]]++;
  38.             }
  39.             if (mp1.size() >= 3) ans++;
  40.             //每次将四个格子中出现颜色两次的格子标记出来,用mp2记录他出现的次数 ,但只标记同种颜色出现次数大于1的格子,因为如果只出现一次,那那种颜色改了和没改没区别
  41.             if (mp1.size() == 2) {
  42.                 for (const auto& t : mp1) {
  43.                     if (t.y > 1) {
  44.                         for (int r = 0; r < 4; r++) {
  45.                             if (mp1[g[i + dx[r]][j + dy[r]]] == t.y) {
  46.                                 mp2[{i + dx[r], j + dy[r]}]++;
  47.                             }
  48.                         }
  49.                     }
  50.                 }
  51.             }
  52.         }
  53.     }
  54.     //将格子数出现次数最多的格子找出来,即为要改变的格子
  55.     for (const auto& t : mp2) {
  56.         if (t.y > maxn) {
  57.             maxn = t.y;
  58.             max_x = t.x.x;
  59.             max_y = t.x.y;
  60.         }
  61.     }
  62.     //要修改的格子周围加上本身总共有9个格子,所以顶多有九种颜色,但由于不可能每个格子颜色不一样,所以,当如果格子数较多时,颜色种数肯定是<9的,而k较小的时候,就在k里面找
  63.     for (int i = 1; i <= min(k, 9); ++i) {
  64.         mp3[i] = 0;
  65.     }
  66.     //找要改成什么颜色,将四个格子中颜色出现两次的格子中的颜色记录下来,出现次数越多,越不选,因为要改成其余的颜色才更可能成为颜色种数>=3的四方格
  67.     for (int i = max_x - 1; i <= max_x; ++i) {
  68.         for (int j = max_y - 1; j <= max_y; ++j) {
  69.             if (!in(i, j)) {
  70.                 continue;
  71.             }
  72.             if (i == n || j == n) {
  73.                 continue;
  74.             }
  75.             mp1.clear();
  76.             for (int r = 0; r < 4; ++r) {
  77.                 mp1[g[i + dx[r]][j + dy[r]]]++;
  78.             }
  79.             if (mp1.size() == 2) {
  80.                 for (int r = 0; r < 4; r++) {
  81.                     mp3[g[i + dx[r]][j + dy[r]]]++;
  82.                 }
  83.             }
  84.         }
  85.     }
  86.     //遍历mp3所记录的目标格子周围的颜色,找出出现次数最少的颜色,修改格子颜色
  87.     for (const auto& t : mp3) {
  88.         if (minn >= t.y) {
  89.             minn = t.y;
  90.             color = t.x;
  91.         }
  92.     }
  93.     g[max_x][max_y] = color;
  94.     //再次重新遍历,记录修改后的种数
  95.     for (int i = 1; i <= n; ++i) {
  96.         for (int j = 1; j <= n; ++j) {
  97.             mp1.clear();
  98.             for (int r = 0; r < 4; ++r) {
  99.                 mp1[g[i + dx[r]][j + dy[r]]]++;
  100.             }
  101.             if (mp1.size() >= 3) cnt++;
  102.         }
  103.     }
  104.     //对比修改前后的数目,取较大值
  105.     printf("%d", max(cnt, ans));
  106.     return 0;
  107. }
  108.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement