[ABC227H] Eat Them All 题解

唐唐题。

思路#

容易发现,我们只要知道了一条边总共经过了多少次(不计方向),我们就可以跑欧拉回路。

如何求一条边经过多少次。

网格总共有十二条边。

但是只有九个点。

我们可以列出九个方程。

具体来说,每个点的经过次数的两倍就是每一条边的访问次数。

这样列出来的方程有一个是无用的。

所以只有八个不同的方程。

还需要枚举四个变量,才能求出所有的出现次数。

并且由于欧拉回路至少需要整张图联通。

所以在找到一组合法的出现次数,还要用并查集判断一下整张图是否联通。

实际效率是很快的,远远跑不满。

时间复杂度:O(ai4)

Code#

#include <bits/stdc++.h>
using namespace std;

int tp;
int a1, a2, a3;
int a4, a5, a6;
int a7, a8, a9;
int b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12;
int c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12;
int ct;
int fa[10];
int hd[10];
char ch[2010];
struct edge {
  int to, nxt, *val; char w;
} e[100];

inline int gf(int x) {
  return (fa[x] == x ? x : fa[x] = gf(fa[x]));
}
inline void mer(int x, int y) {
  fa[gf(x)] = gf(y);
}
inline void add(int x, int y, int*z, char a, char b) {
  e[++ct] = {y, hd[x], z, a}, hd[x] = ct;
  e[++ct] = {x, hd[y], z, b}, hd[y] = ct;
}
inline void dfs(int x) {
  for (int&i = hd[x]; i; i = e[i].nxt) {
    if (*e[i].val > 0) {
      char c = e[i].w;
      (*e[i].val)--;
      dfs(e[i].to);
      ch[++tp] = c;
    }
  }
}

int main() {
  cin >> a1 >> a2 >> a3;
  cin >> a4 >> a5 >> a6;
  cin >> a7 >> a8 >> a9;
  for (b1 = 0; b1 <= min(a1 * 2, a2 * 2); b1++) {
    b3 = 2 * a1 - b1;
    for (b2 = 0; b2 <= min(a2 * 2, a3 * 2); b2++) {
      b4 = 2 * a2 - b1 - b2;
      b5 = 2 * a3 - b2;
      if (b4 < 0) break;
      for (b6 = 0; b6 <= min(a4 * 2, a5 * 2); b6++) {
        b8 = 2 * a4 - b3 - b6;
        if (b8 < 0) break;
        for (b7 = 0; b7 <= min(a5 * 2, a6 * 2); b7++) {
          b9 = 2 * a5 - b4 - b6 - b7;
          b10 = 2 * a6 - b5 - b7;
          b11 = 2 * a7 - b8;
          b12 = 2 * a9 - b10;
          if (b9 + b11 + b12 != a8 * 2 || b9 < 0 || b10 < 0 || b11 < 0 || b12 < 0) continue;
          fa[1] = 1, fa[2] = 2, fa[3] = 3;
          fa[4] = 4, fa[5] = 5, fa[6] = 6;
          fa[7] = 7, fa[8] = 8, fa[9] = 9;
          if (b1) mer(1, 2);
          if (b2) mer(2, 3);
          if (b3) mer(1, 4);
          if (b4) mer(2, 5);
          if (b5) mer(3, 6);
          if (b6) mer(4, 5);
          if (b7) mer(5, 6);
          if (b8) mer(4, 7);
          if (b9) mer(5, 8);
          if (b10) mer(6, 9);
          if (b11) mer(7, 8);
          if (b12) mer(8, 9);
          if (gf(1) != gf(2)) continue;
          if (gf(1) != gf(3)) continue;
          if (gf(1) != gf(4)) continue;
          if (gf(1) != gf(5)) continue;
          if (gf(1) != gf(6)) continue;
          if (gf(1) != gf(7)) continue;
          if (gf(1) != gf(8)) continue;
          if (gf(1) != gf(9)) continue;
          if (b1) add(1, 2, &b1, 'L', 'R');
          if (b2) add(2, 3, &b2, 'L', 'R');
          if (b3) add(1, 4, &b3, 'U', 'D');
          if (b4) add(2, 5, &b4, 'U', 'D');
          if (b5) add(3, 6, &b5, 'U', 'D');
          if (b6) add(4, 5, &b6, 'L', 'R');
          if (b7) add(5, 6, &b7, 'L', 'R');
          if (b8) add(4, 7, &b8, 'U', 'D');
          if (b9) add(5, 8, &b9, 'U', 'D');
          if (b10) add(6, 9, &b10, 'U', 'D');
          if (b11) add(7, 8, &b11, 'L', 'R');
          if (b12) add(8, 9, &b12, 'L', 'R');
          dfs(1);
          for (int i = 1; i <= tp; i++) cout << ch[i]; cout << "\n";
          exit(0);
        }
      }
    }
  }
  cout << "NO\n";
}

作者:JiaY19

出处:https://www.cnblogs.com/JiaY19/p/18460041

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   JiaY19  阅读(6)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示