P7115-[NOIP2020]移球游戏【构造】
正题
题目链接:https://www.luogu.com.cn/problem/P7115
题目大意
\(n+1\)个柱子,前面\(n\)个上面各有\(m\)个球,球有\(n\)种颜色,每种\(m\)个。
你每次可以把一个柱子最上面的球放到另一个上面,要求在\(820000\)次内使得同种颜色的球都在同一个柱子上。
输出方案
\(2\leq n\leq 50,2\leq m\leq 400\)
解题思路
这题好难啊,用的是洛谷题解上的做法。
首先我们枚举一种颜色\(x\),将这种颜色标记为\(1\)其他都为\(0\)。
然后开始的状态是这样的

然后考虑先构造一个全部都是\(0\)的竖列
我们先记录第一柱的\(1\)的个数\(tmp\),然后把第\(n-1\)柱子的\(tmp\)个丢进第\(n+1\)柱,然后把第一柱分离到后面两个柱子(\(1\)的放到\(n\),\(0\)的放到\(n+1\))

然后把原来的\(0\)放到第一柱,然后分离第二柱,如果是\(0\)放到第一柱否则放到第\(n+1\)柱(如果第一柱已经满了就放进\(n+1\)柱)

然后交换一下柱子序号(用个数组存一下就好了)就变成了

然后再考虑构造全\(1\)柱
我们把同理把第\(1\)柱分裂到第\(n\)和第\(n+1\)柱就变成了

此时第\(n+1\)柱子上面全部是\(1\)而第\(n\)柱上面都是\(0\),然后此时我们再把剩下\(n\)个柱子依次分离就能把所有的\(1\)提到最上面,然后把所有的\(1\)集合就好了。
最后弄出\(n-1\)个全\(0\)柱和一个全\(1\)柱我们就可以把全一柱去掉然后缩小\(n\)的值。
一直重复到\(n=2\)时我们发现我们的方法不再适用,需要特别处理。
我们按照前面的方法把第一柱分离到\(2\)和\(3\)

然后把\(0\)和\(1\)丢到第一个柱子,然后再把\(1\)丢进第\(3\)个柱子

然后分离第二个柱子就好了
然后这样就能过了
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=410;
int n,m,a[N][N],cnt[N],p[N];
vector<int> aL,aR;
void mov(int x,int y){
aL.push_back(x);
aR.push_back(y);
a[y][++cnt[y]]=a[x][cnt[x]--];
return;
}
int count(int x,int y){
int ans=0;
for(int i=1;i<=m;i++)
ans+=(a[x][i]==y);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
cnt[i]=m;p[i]=i;
}
p[n+1]=n+1;
for(int k=n;k>=3;k--){
int tmp=count(p[1],k);
for(int i=1;i<=tmp;i++)mov(p[k],p[k+1]);
for(int i=1;i<=m;i++)
if(a[p[1]][cnt[p[1]]]==k)mov(p[1],p[k]);
else mov(p[1],p[k+1]);
for(int i=1;i<=m-tmp;i++)mov(p[k+1],p[1]);
for(int i=1;i<=m;i++)
if(a[p[2]][cnt[p[2]]]==k)mov(p[2],p[k+1]);
else if(cnt[p[1]]<m)mov(p[2],p[1]);
else mov(p[2],p[k+1]);
swap(p[1],p[k]);swap(p[2],p[k+1]);
for(int i=1;i<k;i++){
int tmp=count(p[i],k);
for(int j=1;j<=tmp;j++)mov(p[k],p[k+1]);
for(int j=1;j<=m;j++)
if(a[p[i]][cnt[p[i]]]==k)mov(p[i],p[k]);
else mov(p[i],p[k+1]);
swap(p[i],p[k+1]);swap(p[k],p[i]);
}
for(int i=1;i<k;i++){
while(a[p[i]][cnt[p[i]]]==k)mov(p[i],p[k+1]);
while(cnt[p[i]]<m)mov(p[k],p[i]);
}
}
int tmp=count(p[1],1);
for(int i=1;i<=tmp;i++)mov(p[2],p[3]);
for(int i=1;i<=m;i++)
if(a[1][cnt[p[1]]]==1)mov(p[1],p[2]);
else mov(p[1],p[3]);
for(int i=1;i<=m-tmp;i++)mov(p[3],p[1]);
for(int i=1;i<=tmp;i++)mov(p[2],p[1]);
while(cnt[p[3]])mov(p[3],p[2]);
for(int i=1;i<=tmp;i++)mov(p[1],p[3]);
for(int i=1;i<=m;i++)
if(a[2][cnt[p[2]]]==1)mov(p[2],p[3]);
else mov(p[2],p[1]);
printf("%d\n",aL.size());
for(int i=0;i<aL.size();i++)
printf("%d %d\n",aL[i],aR[i]);
return 0;
}
P7115-[NOIP2020]移球游戏【构造】的更多相关文章
- NOIP2020 移球游戏
Description 给定 \(n+1\) 个栈,前 \(n\) 个栈内有不定的 \(m\) 个元素,最后一个栈为空,每个栈的最大容量为 \(m\) 每种颜色都有 \(m\) 种,求任意一种方法,使 ...
- nyoj_518_取球游戏_201404161738
取球游戏 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个 ...
- nyist 518 取球游戏
http://acm.nyist.net/JudgeOnline/problem.php?pid=518 取球游戏 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 今 ...
- 躲避球游戏ios源码
躲避球游戏源码,有限源码是一个基于cocos2d的躲避球游戏源码的,并且还引用了大家熟悉google广告的,进行推广,已经还有带game center等,游戏操作很简单,用手指按住物体,然后移动物体避 ...
- 取球游戏|2012年蓝桥杯B组题解析第十题-fishers
(25')取球游戏 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断. 我们约定: 每个人从盒子中取出 ...
- 取球游戏_nyoj_518(博弈-蓝桥杯原题).java
取球游戏 时间限制: 1000 ms | 内存限制: 65535 KB 难度: 2 描述 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下 ...
- 放球游戏B
题目描述 校园里在上活动课,Red和Blue两位小朋友在玩一种游戏,他俩在一排N个格子里,自左到右地轮流放小球,每个格子只能放一个小球.第一个人只能放1个球,之后的人最多可以放前一个人的两倍数目的球, ...
- 【题解】放球游戏B
题目描述 校园里在上活动课,Red和Blue两位小朋友在玩一种游戏,他俩在一排N个格子里,自左到右地轮流放小球,每个格子只能放一个小球.第一个人只能放1个球,之后的人最多可以放前一个人的两倍数目的球, ...
- 【题解】放球游戏A
题目描述 校园里在上活动课,Red和Blue两位小朋友在玩一种游戏,他俩在一排N个格子里,自左到右地轮流放小球,每个格子只能放一个小球.每个人一次只能放1至5个球,最后面对没有空格而不能放球的人为输. ...
随机推荐
- js随机显示图片
定义一个图片数组,生成一个随机数对应数据索引. window.onload = choosePic; function choosePic() { var myPix = new Array(&quo ...
- Linux 网络和端口命令
一.查看网口IP等 显示或配置网络设备(网络接口卡)命令 sudo ifconfig 网口及ip信息 sudo ip link 网口信息 sudo ip addr 扫描端口是否开启服务,如下扫描 1至 ...
- 在ubuntu18.04上部署项目时遇到的问题总结
因为在实验室中,有几台空闲的机子,我便选了一台准备做一个本地的服务器,因为买的阿里云学生机和之前用于FQ的机子感觉都不太顺手,阿里的学生机配置稍低,FQ用的服务器延迟太高.开始在centos和ubun ...
- 微信小程序学习笔记三 路由的基本使用
小程序中路由的使用 1.1 页面路由 在小程序中, 所有页面的路由全部由框架进行管理 1.2 页面栈 框架以栈的形式维护了当前的所有页面, 当发生路由切换的时候, 页面栈的表现如下: 1.3 获取当前 ...
- 轻量级日志收集方案Loki
先看看结果有多轻量吧 官方文档:https://grafana.com/docs/loki/latest/ 简介 Grafana Loki 是一个日志聚合工具,它是功能齐全的日志堆栈的核心. Loki ...
- 详细分析MySQL事务日志(undo log)
2.undo log 2.1 基本概念 undo log有两个作用:提供回滚和多个行版本控制(MVCC). 在数据修改的时候,不仅记录了redo,还记录了相对应的undo,如果因为某些原因导致事务失败 ...
- uniapp 设置背景图片
uniapp 由于其特殊机制,导致了背景图片不能引用本地图片.只能通过 转成 base64 来进行设置 附上链接:https://oktools.net/image2base64 图片转成base64 ...
- kubernetes 使用 PV 和 PVC 管理数据存储
文章链接 容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题.首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失--容器以干净的状态(镜像最初的状态)重 ...
- 羽夏笔记——PE结构(不包含.Net)
写在前面 本笔记是由本人独自整理出来的,图片来源于网络.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你 ...
- 初识GDAL
1.GDAL简介 GDAL(Geospatial Data Abstraction Library)是一个用于栅格数据操作的库,是开源地理空间基金会(Open Source Geospatial Fo ...