移球游戏

这篇博客记录了一道NOIP竞赛中的移球问题,作者详细解析了如何从两颜色的特殊情况出发,逐步构建到n种颜色的解决方案。通过分治策略,将所有颜色分为两类并进行操作,展现了问题的解决思路。尽管作者在比赛中只得到了部分分数,但认为这个问题对于理解分治和构造算法非常有帮助。
摘要由CSDN通过智能技术生成

好题笔记

移球游戏

写下此篇,用来记录上一次noip我想了一小时还是没做出来的题(
这一道题是一个典型的构造题,我个人觉得是近几年noip质量最高的题目之一,不仅思维量十分大,而且码量也不小,最主要的是像我这种算法十分匮乏的人也可以想出来。
首先题目可以去洛谷找一下,我们直接开始上正解:
一般构造题目都是从简单的开始想起,我们从只有两颜色的开始,我们要怎么做呢,先假设颜色为1,2 柱子为abc,我们不难发现第一步就是把a上面所有1的个数数出来,假设s个,之后把b上面的s个放到c上,之后把a上的1放到b,2放到c,最后把b上面的全放回a ,之后我们把c上的m-s个放回到a上,之后再把b上的全都放到c上,最后把a上的放到b,最后对c上的进行枚举划分,这是不是就OK了。
没错,我当时就是有了这个思路,于是拿了10分n=2的好成绩(
但是其实这个就是n>2的解决方案
我们想一下,假如我们把所有颜色都划分为1 2 两种颜色,那么我们之后的操作是不是就是上面的操作,那我都说到这里了,不会还有人想不到分治算法吧( 我们定义一个mid,所有颜色<mid的就是颜色1,大于就是颜色2,之后我们去进行分治操作,每一次分治前先把颜色都划分好,之后下一次分治就再一次去进行上一步的操作。
至于分治代码不会写,嗯,众嗦粥汁,我们可以用分支操作中底层的操作去类比,那么我们呢就不会觉得分治难下手了。
这一道题真的很值得干一下,一道不仅仅是分治好题,也是构造好题,写完之后绝对会对分治和构造有更深的理解,其实这两个本来就很像,都是要从简单向难去分析。
最后代码如下

#include<bits/stdc++.h>
using namespace std;

int n,m;//颜色数量和每种球的数量 
int a[55][555];
int top[55]={
   0};
int ans[820005][2],cnt=0;
void mv(int x,int y){
   
	//printf("%d %d\n",x,y);
	ans[++cnt][0]=x;ans[cnt][1]=y;
	a[y][++top[y]]=a[x][top[x]--];//这个是移动和记忆答案的操作 
}
int flag[55]={
   0};
void f(int l,int r){
   
	if(l==r) return;
	int mid=(l+r)>>1;//我们对每一种颜色去进行分治,我们要的是把分治过后的左边和右边分别看成同一种颜色,之后进行纯色移动 
	memset(flag
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值