正题

题目链接:https://www.luogu.com.cn/problem/P7115


题目大意

n+1n+1n+1个柱子,前面nnn个上面各有mmm个球,球有nnn种颜色,每种mmm个。

你每次可以把一个柱子最上面的球放到另一个上面,要求在820000820000820000次内使得同种颜色的球都在同一个柱子上。

输出方案

2≤n≤50,2≤m≤4002\leq n\leq 50,2\leq m\leq 4002≤n≤50,2≤m≤400


解题思路

这题好难啊,用的是洛谷题解上的做法。

首先我们枚举一种颜色xxx,将这种颜色标记为111其他都为000。

然后开始的状态是这样的

然后考虑先构造一个全部都是000的竖列

我们先记录第一柱的111的个数tmptmptmp,然后把第n−1n-1n−1柱子的tmptmptmp个丢进第n+1n+1n+1柱,然后把第一柱分离到后面两个柱子(111的放到nnn,000的放到n+1n+1n+1)

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


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

然后再考虑构造全111柱

我们把同理把第111柱分裂到第nnn和第n+1n+1n+1柱就变成了

此时第n+1n+1n+1柱子上面全部是111而第nnn柱上面都是000,然后此时我们再把剩下nnn个柱子依次分离就能把所有的111提到最上面,然后把所有的111集合就好了。

最后弄出n−1n-1n−1个全000柱和一个全111柱我们就可以把全一柱去掉然后缩小nnn的值。

一直重复到n=2n=2n=2时我们发现我们的方法不再适用,需要特别处理。

我们按照前面的方法把第一柱分离到222和333

然后把000和111丢到第一个柱子,然后再把111丢进第333个柱子

然后分离第二个柱子就好了

然后这样就能过了


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]移球游戏【构造】相关推荐

  1. NOIP2020洛谷P7115:移球游戏(分治)

    解析 先考虑n=2的情况 可以利用一个空队在不超过5m的操作次数下把两个满队还原 如何推广? 考虑分治 把[l,mid]的球看成同色,[mid+1,r]的球看成同色 在左右两两匹配柱子进行n=2的还原 ...

  2. nyoj_518_取球游戏_201404161738

    取球游戏 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并 ...

  3. 蓝桥杯--2012--取球游戏

     十.取球游戏 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断. 我们约定: 每个人从盒子中取出 ...

  4. NYOJ 518 取球游戏

    取球游戏 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并 ...

  5. 拦截游戏窗口被移动_「维维足球pro-教案」50个传控踢法练习之(一、二)追球游戏...

    如图所示,上方黄色虚线代表球的移动,中间黑色实线代表球员移动,下方黑色虚曲线代表球员带球移动. 术语:卡斯特球员(kaasters):荷兰语"回传".指站在指定地点,在一或两次触球 ...

  6. 支付宝之小鸡拍球游戏(C++)

    小鸡拍球 [问题描述]"蚂蚁庄园"的小鸡拍球游戏中,有三种可能的得分:5分.8分和10分.现从键盘输入一个整数的得分值,请输出该局游戏可能的得分组合. [输入形式]输入只有一行,包 ...

  7. android 传感器小游戏,重力感应球游戏

    重力感应球游戏是一款休闲益智类闯关游戏,有采用卡通的画风设计,超有趣的闯关玩法模式,在这里各种不同的游戏关卡等你来挑战,带给玩家最轻松有趣的闯关乐趣,非常的有意思,喜欢的小伙伴还在等什么,快来下载看看 ...

  8. 制作滚球游戏学习Unity3D

    从创建项目开始 创建一个项目 打开unity,在Projects中可以查看当前的本地项目或者云端项目,点击New project或者右上角的New都可以新建项目. 然后在1处填写创建项目的名称,2处选 ...

  9. python 乒乓球_python使用pygame实现笑脸乒乓球弹珠球游戏

    今天我们用python和pygame实现一个乒乓球的小游戏,或者叫弹珠球游戏. 笑脸乒乓球游戏功能介绍 乒乓球游戏功能如下: 乒乓球从屏幕上方落下,用鼠标来移动球拍,使其反弹回去,并获得得分,如果没有 ...

最新文章

  1. 自动驾驶外卖上线,美团即将配送一切
  2. 开发效率不高?墙裂推荐这十款精选 IntelliJ IDEA 插件
  3. Circuit Breaker(电路熔断器)模式原理
  4. 3月2日,阿里云开源 PolarDB 企业级架构即将发布
  5. 如何查看git是否添加到环境变量 - cmd篇
  6. Windows Vista for Developers——第二部分:深入分析任务对话框
  7. 删除office2016专业版多余组件
  8. (剑指Offer)面试题46:求1+2+3+....+n
  9. R开发环境(Eclipse+StatET)
  10. C++之queue和dequeu用法
  11. 【mybatis】学习笔记之conf.xml与mapper.xml配置
  12. 递归求n的阶乘不溢出_面试官:说一说递归如何优化尾递归优化
  13. java canvas画矩形,HTML5 编程之Canvas
  14. 动态时间规整—DTW算法
  15. 计算机性能怎么测试软件,如何测试电脑性能|检测电脑性能的方法
  16. SSM框架集合(2021)基础使用
  17. 加权平均数的例子_加权平均数公式(加权平均数公式例子)
  18. 2010年北京大学软件与微电子学院毕业生就业去向(官方不完全统计)
  19. kangle虚拟主机系统easypanel使用教程
  20. @ds实现多数据源切换及解决事务失效问题

热门文章

  1. 微信 小程序 python 渲染_微信小程序渲染html内容
  2. 用keil怎么擦除_分享STM32 FLASH 擦除(以及防止误擦除程序代码)、写入
  3. python实例化对象是什么意思_请帮我理解python对象的实例化.
  4. leetcode20. 有效的括号
  5. jdbc的预处理中如何处理模糊查询
  6. [JavaWeb-JavaScript]JavaScript_Math数学对象
  7. tof摄像头手势识别_一种基于TOF手势识别的控制系统的制作方法
  8. HTMLCSS 超简单的前端设计入门-1!
  9. word List39
  10. 广东省计算机媒体大赛,广东省大学生计算机设计大赛