正题

题目链接: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

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<vector>
  5. using namespace std;
  6. const int N=410;
  7. int n,m,a[N][N],cnt[N],p[N];
  8. vector<int> aL,aR;
  9. void mov(int x,int y){
  10. aL.push_back(x);
  11. aR.push_back(y);
  12. a[y][++cnt[y]]=a[x][cnt[x]--];
  13. return;
  14. }
  15. int count(int x,int y){
  16. int ans=0;
  17. for(int i=1;i<=m;i++)
  18. ans+=(a[x][i]==y);
  19. return ans;
  20. }
  21. int main()
  22. {
  23. scanf("%d%d",&n,&m);
  24. for(int i=1;i<=n;i++){
  25. for(int j=1;j<=m;j++)
  26. scanf("%d",&a[i][j]);
  27. cnt[i]=m;p[i]=i;
  28. }
  29. p[n+1]=n+1;
  30. for(int k=n;k>=3;k--){
  31. int tmp=count(p[1],k);
  32. for(int i=1;i<=tmp;i++)mov(p[k],p[k+1]);
  33. for(int i=1;i<=m;i++)
  34. if(a[p[1]][cnt[p[1]]]==k)mov(p[1],p[k]);
  35. else mov(p[1],p[k+1]);
  36. for(int i=1;i<=m-tmp;i++)mov(p[k+1],p[1]);
  37. for(int i=1;i<=m;i++)
  38. if(a[p[2]][cnt[p[2]]]==k)mov(p[2],p[k+1]);
  39. else if(cnt[p[1]]<m)mov(p[2],p[1]);
  40. else mov(p[2],p[k+1]);
  41. swap(p[1],p[k]);swap(p[2],p[k+1]);
  42. for(int i=1;i<k;i++){
  43. int tmp=count(p[i],k);
  44. for(int j=1;j<=tmp;j++)mov(p[k],p[k+1]);
  45. for(int j=1;j<=m;j++)
  46. if(a[p[i]][cnt[p[i]]]==k)mov(p[i],p[k]);
  47. else mov(p[i],p[k+1]);
  48. swap(p[i],p[k+1]);swap(p[k],p[i]);
  49. }
  50. for(int i=1;i<k;i++){
  51. while(a[p[i]][cnt[p[i]]]==k)mov(p[i],p[k+1]);
  52. while(cnt[p[i]]<m)mov(p[k],p[i]);
  53. }
  54. }
  55. int tmp=count(p[1],1);
  56. for(int i=1;i<=tmp;i++)mov(p[2],p[3]);
  57. for(int i=1;i<=m;i++)
  58. if(a[1][cnt[p[1]]]==1)mov(p[1],p[2]);
  59. else mov(p[1],p[3]);
  60. for(int i=1;i<=m-tmp;i++)mov(p[3],p[1]);
  61. for(int i=1;i<=tmp;i++)mov(p[2],p[1]);
  62. while(cnt[p[3]])mov(p[3],p[2]);
  63. for(int i=1;i<=tmp;i++)mov(p[1],p[3]);
  64. for(int i=1;i<=m;i++)
  65. if(a[2][cnt[p[2]]]==1)mov(p[2],p[3]);
  66. else mov(p[2],p[1]);
  67. printf("%d\n",aL.size());
  68. for(int i=0;i<aL.size();i++)
  69. printf("%d %d\n",aL[i],aR[i]);
  70. return 0;
  71. }

P7115-[NOIP2020]移球游戏【构造】的更多相关文章

  1. NOIP2020 移球游戏

    Description 给定 \(n+1\) 个栈,前 \(n\) 个栈内有不定的 \(m\) 个元素,最后一个栈为空,每个栈的最大容量为 \(m\) 每种颜色都有 \(m\) 种,求任意一种方法,使 ...

  2. nyoj_518_取球游戏_201404161738

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

  3. nyist 518 取球游戏

    http://acm.nyist.net/JudgeOnline/problem.php?pid=518 取球游戏 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 今 ...

  4. 躲避球游戏ios源码

    躲避球游戏源码,有限源码是一个基于cocos2d的躲避球游戏源码的,并且还引用了大家熟悉google广告的,进行推广,已经还有带game center等,游戏操作很简单,用手指按住物体,然后移动物体避 ...

  5. 取球游戏|2012年蓝桥杯B组题解析第十题-fishers

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

  6. 取球游戏_nyoj_518(博弈-蓝桥杯原题).java

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

  7. 放球游戏B

    题目描述 校园里在上活动课,Red和Blue两位小朋友在玩一种游戏,他俩在一排N个格子里,自左到右地轮流放小球,每个格子只能放一个小球.第一个人只能放1个球,之后的人最多可以放前一个人的两倍数目的球, ...

  8. 【题解】放球游戏B

    题目描述 校园里在上活动课,Red和Blue两位小朋友在玩一种游戏,他俩在一排N个格子里,自左到右地轮流放小球,每个格子只能放一个小球.第一个人只能放1个球,之后的人最多可以放前一个人的两倍数目的球, ...

  9. 【题解】放球游戏A

    题目描述 校园里在上活动课,Red和Blue两位小朋友在玩一种游戏,他俩在一排N个格子里,自左到右地轮流放小球,每个格子只能放一个小球.每个人一次只能放1至5个球,最后面对没有空格而不能放球的人为输. ...

随机推荐

  1. 安装RHEL7配置本地yum源 -- yum不能安装时,在本地安装,亲测成功

    RHEL7 本地yum源配置我们在安装Redhat的时候一般都不会填写注册信息,因为该产品是要购买的,所以我们在使用安装好的Redhat时有的功能是受限的,使用yum源install就是其中之一.那么 ...

  2. Java:学习什么是多线程

    线程是什么 进程是对CPU的抽象,而线程更细化了进程的运行流程 先看一下这个图 线程和进程的关系有 进程中就是线程在执行,所有(主)线程执行完了进程也就结束了 多个线程从1秒钟是同时运行完成,从1纳秒 ...

  3. 在WPF中的ItemsControl中使用事件和命令(Using events and Commands within ItemsControl in WPF)

    Say I have a standard WPF ItemsControl bound to an ObservableCollection of "Dog" objects l ...

  4. Python使用flask架构、跨域

    from flask import Flask import json from flask_cors import CORS Server = Flask(__name__) cors = CORS ...

  5. Spring详解(十)加载配置文件

    在项目中有些参数经常需要修改,或者后期可能会有改动时,那我们最好把这些参数放到properties文件中,在源代码中读取properties里面的配置,这样后期只需要改动properties文件即可, ...

  6. 八:Filter(过滤器)

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...

  7. 网页前端video播放m3u8(HLS)

    网页前端video播放m3u8(HLS) HLS (HTTP Live Streaming)是Apple公司研发的流媒体传输技术,包括一个m3u8的索引文件.多个ts分片文件和key加密串文件.这项技 ...

  8. 如何配置https

    1.创建证书:keytool -genkey -alias wsria -keyalg RSA -keystore d:/keys/wsriakey 其中姓氏和组织名称为登录时的域名:如localho ...

  9. springboot:嵌套使用异步注解@Async还会异步执行吗

    一.引言 在前边的文章<[springboot:使用异步注解@Async的那些坑>中介绍了使用@Async注解获取任务执行结果的错误用法,今天来分享下另外一种常见的错误. 二.代码演示 下 ...

  10. mybatis gengeator一键生成