当前位置: 首页 > news >正文

noip6 多校1

11.12

t1

\(O(nm^2)\)是简单的。

发挥人类智慧发现每次最优只在前面较少的状态。

于是可过。

其实人类智慧有证明的。

考虑若最大值越大,则选的次数越小,反之亦然。

平均一下就过了。

code

t1
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
const int M = 5e3 + 10;
int n, m;
int a[N], b[N], pos[M];
int dp[N][M];signed main()
{freopen("crazy.in", "r", stdin);freopen("crazy.out", "w", stdout);ios::sync_with_stdio(0);cin.tie(0);cin >> n >> m;for (int i = 1; i <= n; ++i)cin >> a[i], b[i] = a[i];sort(b + 1, b + 1 + n);for (int i = 0; i <= m; ++i)pos[i] = upper_bound(b + 1, b + 1 + n, i) - b - 1;memset(dp, 0x3f, sizeof(dp));dp[0][0] = 0;for (int i = 1; i <= n; ++i){for (int j = 0; j <= m; ++j)for (int k = max(j - 100, 0); k <= j; ++k)dp[i][j] = min(dp[i][j], dp[i - 1][k] + n - pos[j - k]);}cout << dp[n][m];return 0;
}

t2

dp加一吨特判。

赛事困+左右脑互搏,写了个抽象东西dfs。

本质就是dp中的一种转移,我也不知道为啥写个dfs转移。

code

t2
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int T, n, m;
int a[N][N], dp[N][N];int val(int x, int y, int c, int d)
{if (a[x][y] ^ a[c][d])return (a[c][d] && !a[x][y]);elsereturn 0;
}inline void solve()
{cin >> n >> m;for (int i = 1; i <= n; ++i)for (int j = 1; j <= m; ++j)cin >> a[i][j];if ((n == 1 && m == 1 && a[1][1]) || (n * m == 2 && (a[1][1] ^ a[n][m]))){cout << "Impossible\n";return;}if (n == 1){int tot = 0, lst = 0;for (int i = 1; i <= m; ++i){if (a[1][i])lst = i, ++tot;dp[1][i] = dp[1][i - 1] + val(1, i - 1, 1, i);}if (tot == 1)dp[n][m] = 2 + ((lst - 1) <= 1 && (m - lst) <= 1);cout << dp[n][m] << "\n";return;}if (m == 1){int tot = 0, lst = 0;for (int i = 1; i <= n; ++i){if (a[i][1])lst = i, ++tot;dp[i][1] = dp[i - 1][1] + val(i - 1, 1, i, 1);}if (tot == 1)dp[n][m] = 2 + ((lst - 1) <= 1 && (n - lst) <= 1);cout << dp[n][m] << "\n";return;}for (int i = 1; i <= n; ++i){for (int j = 1; j <= m; ++j){if (i == 1 && j == 1)dp[i][j] = a[i][j];else if (i == 1)dp[i][j] = dp[i][j - 1] + val(i, j - 1, i, j);else if (j == 1)dp[i][j] = dp[i - 1][j] + val(i - 1, j, i, j);elsedp[i][j] = min(dp[i][j - 1] + val(i, j - 1, i, j), dp[i - 1][j] + val(i - 1, j, i, j));}}cout << dp[n][m] << "\n";
}signed main()
{freopen("flip.in", "r", stdin);freopen("flip.out", "w", stdout);ios::sync_with_stdio(0);cin.tie(0);cin >> T;while (T--)solve();return 0;
}

t3

你直接出那个ds都是吉司机线段树。

然后还变成神秘东西???

神人题,神人做。

t4

如果发现了是最短路就可以秒。

相邻两个非冰的块次数为2。

每次向上下左右扩展到的第一个冰的之前的块次数为1(单向边)。

然后dij即可。

code

t4
#include <bits/stdc++.h>
#define pir pair<int, int>
#define fi first
#define se second
using namespace std;
const int N = 1e3 + 10;
int n, m, x1, y3, x2, y2;
vector<pir> e[N * N];
char c[N][N];
int dis[N * N];
bool flag[N * N];
priority_queue<pir, vector<pir>, greater<pir>> q;inline int get_id(int i, int j) { return (i - 1) * m + j; }inline void dij(int op)
{memset(dis, 0x3f, sizeof(dis));memset(flag, 0, sizeof(flag));dis[op] = 0;q.push(make_pair(0, op));while (q.size()){int x = q.top().se;q.pop();if (flag[x])continue;flag[x] = 1;for (auto y : e[x]){if (dis[y.fi] > dis[x] + y.se){dis[y.fi] = dis[x] + y.se;q.push(make_pair(dis[y.fi], y.fi));}}}
}signed main()
{freopen("skate.in", "r", stdin);freopen("skate.out", "w", stdout);ios::sync_with_stdio(0);cin.tie(0);cin >> n >> m;for (int i = 1; i <= n; ++i)for (int j = 1; j <= m; ++j)cin >> c[i][j];for (int i = 1; i <= n; ++i)for (int j = 1; j <= m; ++j){if (c[i][j] == '#')continue;if (c[i - 1][j] == '.')e[get_id(i, j)].emplace_back(make_pair(get_id(i - 1, j), 2));if (c[i][j - 1] == '.')e[get_id(i, j)].emplace_back(make_pair(get_id(i, j - 1), 2));if (c[i + 1][j] == '.')e[get_id(i, j)].emplace_back(make_pair(get_id(i + 1, j), 2));if (c[i][j + 1] == '.')e[get_id(i, j)].emplace_back(make_pair(get_id(i, j + 1), 2));int nx = i, ny = j;while (c[nx][ny] == '.') // up--nx;++nx;if (!(nx == i && ny == j))e[get_id(i, j)].emplace_back(make_pair(get_id(nx, ny), 1));nx = i, ny = j;while (c[nx][ny] == '.') // left--ny;++ny;if (!(nx == i && ny == j))e[get_id(i, j)].emplace_back(make_pair(get_id(nx, ny), 1));// cout << "nx=" << nx << " ny=" << ny << "\n";nx = i, ny = j;while (c[nx][ny] == '.') // down++nx;--nx;if (!(nx == i && ny == j))e[get_id(i, j)].emplace_back(make_pair(get_id(nx, ny), 1));// cout << "nx=" << nx << " ny=" << ny << "\n";nx = i, ny = j;while (c[nx][ny] == '.') // right++ny;--ny;if (!(nx == i && ny == j))e[get_id(i, j)].emplace_back(make_pair(get_id(nx, ny), 1));}cin >> x1 >> y3 >> x2 >> y2;dij(get_id(x1, y3));cout << (dis[get_id(x2, y2)] > 100000000 ? -1 : dis[get_id(x2, y2)]);return 0;
}

紧急写的(10min),仓促。

http://www.jsqmd.com/news/38850/

相关文章:

  • CCPC2025哈尔滨站-H. 匹配
  • 通过开发环境部署工具安装qt相关c++开发环境
  • 第23天(简单题中等题 二分查找)
  • Cinema4D 2025保姆级下载安装教程|含安装包获取+新手入门指南
  • 2014 吉林省赛题解 | CCUT应用OJ题解——F[X] + X = N
  • 洛谷 P4859 已经没有什么好害怕的了 题解(DP,二项式反演)
  • 01321:棋盘问题
  • C 变量的作用域与生存周期
  • 模式识别与机器学习课程笔记(11):深度学习 - 详解
  • 05.创建型 - 简单工厂模式(Simple Factory Pattern)
  • RabbitMQ延迟队列rabbitmq_delayed_message_exchange
  • HaluMem:揭示当前AI记忆系统的系统性缺陷,系统失效率超50%
  • 团队作业2-需求规格说明书
  • Mac安装Visual Studio 2019.dmg详细步骤(附图解,小白也能懂,附安装包)
  • 20251112 正睿
  • 如何根据色带计算电阻阻值
  • 25.11.12 差分约束算法
  • 11/12
  • Linux C/C++ 学习日记(27):KCP协议(三):源码分析与使用示例 - 实践
  • 解决Cursor编辑器无法通过include path识别C++头文件的问题
  • 麒麟桌面系统2503安装openjdk21
  • 重组蛋白基础与技术概述
  • Day36(6)-F:\硕士阶段\Java\课程代码\后端\web-ai-code\web-ai-project01
  • E. Journey
  • Dynamics 365 Field Service跨站脚本欺骗漏洞分析
  • Linux优秀的系统--信号(3--信号的保存、阻塞)
  • 深入解析:SQL提数与数据分析指南
  • 日报11.12
  • 大家来写 ICPC 西安(没写完)
  • [译] 省略 Async 与 Await