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

题解:P15346 [TOIP 2025] 煎饼摊

一眼看成了 [NOIP2020] 移球游戏,不过这题比移球游戏简单多了。

考虑如何在不破坏已归位煎饼的同时将一个新的煎饼归位。

首先找到第一个未归位的位置,以及一个应该放到这个位置的煎饼,例如下面这样:(每一列为一叠煎饼,上面是上面,下面是下面,字符 . 表示空)

 1   a   . 1   b   . 
[x] (1)  . 1   c   . 1   d   . 
-----------

可以通过以下七步将 (1) 放到第一列中:

  1. (1) 上面的煎饼移动到空白列;
 1   .   . 1   .   . 
[x] (1)  . 1   c   a 1   d   b 
-----------
  1. (1) 移动到空白列;
 1   .   . 1   .   . 
[x]  .  (1)1   c   a 1   d   b 
-----------
  1. 将空白列移动到第二列(以上三步的目的是将 (1) 移动到所在列顶端);
 1  (1)  . 1   a   . 
[x]  b   . 1   c   . 1   d   . 
-----------
  1. [x] 及以上的煎饼移动到空白列;
 .  (1)  . .   a   . .   b   1 1   c   1 1   d  [x]
-----------
  1. (1) 移动到第一列;
 .   .   . .   a   . 
(1)  b   1 1   c   1 1   d  [x]
-----------
  1. [x] 上面的煎饼移动到第一列;
 1   .   . 1   a   . 
(1)  b   . 1   c   . 1   d  [x]
-----------
  1. [x] 移动到第二列。
 1  [x]  . 1   a   . 
(1)  b   . 1   c   . 1   d   . 
-----------

至此,我们把 (1) 归位了。

我们至多需要归位 \(nm\) 个煎饼,因此操作次数最多为 \(7nm\)

代码:

// Problem: P15346 [TOIP 2025] 煎饼摊
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P15346
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)//By: OIer rui_er
#include <bits/stdc++.h>
#define rep(x, y, z) for(int x = (y); x <= (z); ++x)
#define per(x, y, z) for(int x = (y); x >= (z); --x)
#define debug(format...) fprintf(stderr, format)
#define fileIO(s) do {freopen(s".in", "r", stdin); freopen(s".out", "w", stdout);} while(false)
#define endl '\n'
using namespace std;
typedef long long ll;mt19937 rnd(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
int randint(int L, int R) {uniform_int_distribution<int> dist(L, R);return dist(rnd);
}template<typename T> void chkmin(T& x, T y) {if(y < x) x = y;}
template<typename T> void chkmax(T& x, T y) {if(x < y) x = y;}template<int mod>
inline unsigned int down(unsigned int x) {return x >= mod ? x - mod : x;
}template<int mod>
struct Modint {unsigned int x;Modint() = default;Modint(unsigned int x) : x(x) {}friend istream& operator>>(istream& in, Modint& a) {return in >> a.x;}friend ostream& operator<<(ostream& out, Modint a) {return out << a.x;}friend Modint operator+(Modint a, Modint b) {return down<mod>(a.x + b.x);}friend Modint operator-(Modint a, Modint b) {return down<mod>(a.x - b.x + mod);}friend Modint operator*(Modint a, Modint b) {return 1ULL * a.x * b.x % mod;}friend Modint operator/(Modint a, Modint b) {return a * ~b;}friend Modint operator^(Modint a, int b) {Modint ans = 1; for(; b; b >>= 1, a *= a) if(b & 1) ans *= a; return ans;}friend Modint operator~(Modint a) {return a ^ (mod - 2);}friend Modint operator-(Modint a) {return down<mod>(mod - a.x);}friend Modint& operator+=(Modint& a, Modint b) {return a = a + b;}friend Modint& operator-=(Modint& a, Modint b) {return a = a - b;}friend Modint& operator*=(Modint& a, Modint b) {return a = a * b;}friend Modint& operator/=(Modint& a, Modint b) {return a = a / b;}friend Modint& operator^=(Modint& a, int b) {return a = a ^ b;}friend Modint& operator++(Modint& a) {return a += 1;}friend Modint operator++(Modint& a, int) {Modint x = a; a += 1; return x;}friend Modint& operator--(Modint& a) {return a -= 1;}friend Modint operator--(Modint& a, int) {Modint x = a; a -= 1; return x;}friend bool operator==(Modint a, Modint b) {return a.x == b.x;}friend bool operator!=(Modint a, Modint b) {return !(a == b);}
};const int N = 55;int n, m, a[N][N], sz[N];
vector<tuple<int, int, int>> ans;void operate(int x, int y, int z) {if(y > sz[x]) return;ans.emplace_back(x, sz[x] - y + 1, z);rep(i, y, sz[x]) a[z][++sz[z]] = a[x][i];sz[x] = y - 1;
}int main() {ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);cin >> m >> n;rep(i, 1, n) rep(j, 1, m) cin >> a[i][j];rep(i, 1, n) sz[i] = m;while(true) {int ax = -1, ay = -1;rep(i, 1, n) {rep(j, 1, m) {if(a[i][j] != i) {ax = i;ay = j;break;}}if(ax != -1 && ay != -1) break;}if(ax == -1 && ay == -1) break;int bx = -1, by = -1;rep(i, 1, n) {rep(j, 1, m) {if(i != ax && a[i][j] == ax) {bx = i;by = j;break;}}if(bx != -1 && by != -1) break;}operate(bx, by + 1, n + 1);operate(bx, by, n + 1);operate(n + 1, 1, bx);operate(ax, ay, n + 1);operate(bx, m, ax);operate(n + 1, 2, ax);operate(n + 1, 1, bx);}cout << ans.size() << endl;for(auto [x, y, z]: ans) cout << x << " " << y << " " << z << endl;// rep(i, 1, n + 1) {// cout << "Stack #" << i << ": ";// rep(j, 1, sz[i]) cout << a[i][j] << " ";// cout << endl;// }return 0;
}
http://www.jsqmd.com/news/481327/

相关文章:

  • 从此告别拖延!多场景适配降重神器 —— 千笔·降AI率助手
  • 2026年别墅豪宅业主必看:北京旭格门窗厂家选型指南与精准适配分析 - 品牌推荐
  • 分析2026年上海人才引进落户流程,靠谱办理公司怎么选 - 工业推荐榜
  • 2026年用户口碑实证:北京旭格门窗厂家服务商推荐与真实案例价值分析 - 品牌推荐
  • 北京/上海/深圳/杭州/南京/无锡高端腕表材质养护+外观修复指南,36品牌颜值守护+正规门店护航 - 时光修表匠
  • 网格隐藏技术在ANSYS仿真分析中的应用研究
  • 分享落户中介选择经验,好人事的口碑怎样? - mypinpai
  • 探寻江苏机器外壳钣金生产厂,技术强的厂家怎么选 - 工业品网
  • 高端建筑外维护系统趋势:2026年北京旭格门窗厂家市场格局与核心玩家解读 - 品牌推荐
  • 【深度解析】王婆大虾底料工业化生产技术:原理、优势与应用实践 - 速递信息
  • 搞懂js/ts的事件循环机制
  • 2026年别墅豪宅业主必看:北京威卢克斯天窗厂家选型指南与精准适配分析 - 品牌推荐
  • 分析售后完善的离婚律师团队,如何选择靠谱的 - 工业设备
  • 了解团团圆家具价格贵不贵?餐桌椅性价比高不高? - myqiye
  • 哪个论文降重工具最好用?2026年10个主流降重网站综合测评对比! - agihub
  • 说说上海落户哪个办理机构成功率高,这些品牌值得推荐 - 工业推荐榜
  • 实测主流论文降重工具效果!哪个工具网站更好用性价比更高? - 老米_专讲AIGC率
  • 避坑 3:Docker 致命大坑!容器一删,业务数据全没了?3 套解决方案,直接抄,不翻车
  • 进口油封品牌十大排名2026最新版,高端品质优选指南 - 速递信息
  • 北京/上海/深圳/杭州/南京/无锡高端腕表配件选择+真伪鉴别指南,36品牌适配+正规门店保障 - 时光修表匠
  • 测完15款论文降重工具我悟了:2026论文降重,认准这一个就够了! - 晨晨_分享AI
  • 2026年利安达牌病理科质控柱推荐:精准匹配医疗场景需求 - 速递信息
  • 2026深度测评10款论文降重工具:3个免费方法亲测有效!谁是降重的最优解?(附论文降重避坑指南) - 仙仙学姐测评
  • 讲讲2026年上海老牌上海落户公司,服务口碑好的有哪些 - mypinpai
  • 2026好用的特种调节阀定制厂家,产品功能评测来袭,行业内调节阀精选优质品牌解析 - 品牌推荐师
  • 赴津看病就医有帮手 天津陪诊机构全梳理 正规选择看这里 - 品牌排行榜单
  • 一次纠正,全队同步!我的OpenClaw AI Agent 3层记忆系统,彻底告别“失忆”烦恼
  • 2026环保装修趋势报告:从“装修达标”到“终身安心”的范式转移 - 速递信息
  • NMN牌子如何选择?2026年NMN品牌深度测评,多维度匹配你的抗衰需求 - 速递信息
  • 3月12日web前端开发