Time limit: 1000ms         Memory limits: 256MB

Description

2048曾经是一款风靡全球的小游戏。
今天,我们换一种方式来玩这个小游戏。
现在,你有一个双端队列,你只能把元素从左端或从右端放入双端队列中。一旦放入就不得取出。放入后,若队列中有连续两个相同的元素,它们将自动合并变成一个新的元素——原来那两个元素的和。若新的元素与它相邻的元素相同,则继续合并……
如:双端队列中有2, 4, 16三个元素。若将2从左端插入双端队列中,该队列将变成8, 16。若将2从右端插入双端队列中,该队列将变成2, 4, 16, 2。
一开始,双端队列为空。我们将给你一些数,你需要依次插入到双端队列中。问是否存在一种操作方案,使得双端队列最后只剩下一个数。

Input

第一行为一个整数 $T$ ,表示数据组数。
对于每组测试数据:
第一行一个整数 $n$ ,表示我们给你的数的个数。
接下来一行 $n$ 个数,表示我们给你的数 $a_i$ 。这些数都是2的非负整数次方,即对于每个 $i$ 都存在一个整数 $k$ 满足$ k≥0$ 且$ a_i=2^k $。

Output

对于每组数据,若不存在一种操作方案使得双端队列最后只剩一个数,则输出no。否则,输出一个长度为n的字符串,其中若第i个数从左边插入到双端队列,则第i个字符为$ l$ ;若第$i$个数从右边插入到双端队列,则第$i$个字符为$ r$ 。

Sample Input

3
9
2 8 4 1 1 4 4 4 4
5
2 16 4 8 2
3
2 2 2

Sample Output

rrrlllrrr
no
no

HINT

样例1解释
1、从右边插入2,双端队列变为2
2、从右边插入8,双端队列变为2 8
3、从右边插入4,双端队列变为2 8 4
4、从左边插入1,双端队列变为1 2 8 4
5、从左边插入1,双端队列变为4 8 4
6、从左边插入4,双端队列变为16 4
7、从右边插入4,双端队列变为16 8
8、从右边插入4,双端队列变为16 8 4
9、从右边插入4,双端队列变为32

数据范围与约定
对于20%的数据,$ n≤19,T≤100$
对于所有数据, $1≤n≤1000$, $\sum\limits_{i=1}^{n} a_i <=2^{13}$,其中$ n>20$的数据不超过150组。

[吐槽]

  玄妙的一题!

  嗯场上天真地认为自己搞出来了结果。。对拍停了很棒棒qwq

[题解]

  看完正解之后感觉整个人都飞起来了qwq

  

  考虑怎样才能消完

  嗯这是很自然的想法吧当然是先看最后排出来怎样的序列才能消完啦

  然后就会发现一个只有最后得到的是这样的先递增再递减的序列才可能消完,也就是:

  一个序列

  $l_1,l_2,l_3,l_4,...,l_{k0}, r_1,r_2,r_3,...,r_{k1} $

   $(l_1<=l_2<=l_3<=...<=l_{k0}>=r_1>=r_2>=r_3>=...>=r_{k1})$

  

  接着还会发现一个有趣的事情

  如果说我知道了$LeftPart$(也就是递增部分),$RightPart$(递减部分)自然也就确定了

  然后还会发现题目中的条件:$\sum\limits_{i=1}^{n} a_i <=2^{13}$

  也就是说,如果枚举$l$的状态数至多只会有$2^{13}$

  很友善啊

  好的于是就可以考虑dp啦

  考虑状压dp

  由于知道了$LeftPart$, $RightPart$也确定了,所以我们的状态显然就只用记录$l$部分就好

  定义$f_{i,j}$表示处理到第$i$个数,$l$部分的和为$j$这一状态是由哪个状态转移过来的

  之所以要用这么奇怪的记录方式是因为。。要输出方案

  此外再定义$g_{i,j}$表示处理到第$i$个数,$l$部分的和为$j$这一状态,第$i$个数从哪边放

  显然这么定义完了之后输出就是反过来找一遍就好啦

  

  那么接下来就是转移了

  (二进制是好东西呀lowbit和highbit这种东西十分的吼啊)

  首先看一下那个合并方式

  会发现其实如果以二进制的方式来看的话,那些奇奇怪怪的合并啊之类的东西已经自动帮你处理好了

  所以判断起来会很方便

  

  对于第$i$个数

  我们看它可以放在左边还是右边,可以放过去的条件就是$a_i<=$最左边/最右边那个数

  判断的话,因为我们要求每一步操作之后都能让序列保持上面提到的合法性质

  所以可以保证到最左边/最右边的数值是最小的

  这样一来就可以直接用lowbit(也就是转为二进制后最靠右边的1代表的数值)来取得最边上的数的值了

  

  (以下步骤的前提都是$f_{i-1,j}$有解)

  如果往右边放的话就有

  $f_{i,j}=j$                $g_{i,j}=r$

  如果往左边放的话就有

  $f_{i,j+a_i}=j$             $g_{i,j}=l$

  但是同时要处理一下$j+a_i>=highbit(RightPart)$(也就是递减部分的最大的那个数值)的情况

  为啥?因为我们的$f_{i,j}$中的$j$记录的是$LeftPart$(递增部分)的和

  而当出现上述情况的时候,说明此时$LeftPart$这边所有的数已经合成了一个比$RightPart$大或者相等的数

  这时我们可以将$LeftPart$这边的这个大数直接归为$RightPart$,然后$LeftPart$的和清零

  好处?这样最后查询ans的时候,直接看$f_{n,0}$就可以啦

  然后就很愉快滴做完啦ovo

  噢终极无敌玄妙

[一些细节]

  嗯因为我们最后查ans的时候,只有在有解的时候才是正确的(否则无法保证最后合成的是一个数)

  所以对于那种本身和都不是一个2的若干次方的输入,直接输no

  判断这个的话直接看$lowbit(x)$是否等于$x$就好啦

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=;
const int MAXM=(<<)+;
int highbit[MAXM],sum[MAXN];
int a[MAXN],f[MAXN][MAXM];
char rec[MAXN][MAXM];
int n,T,ans;
int get_h();
int print(int x,int y);
int lowbit(int x) {return x&-x;} int main()
{
// freopen("a.in","r",stdin); scanf("%d",&T);
get_h();
int tmp;
for (int o=;o<=T;++o)
{
scanf("%d",&n);
sum[]=;
for (int i=;i<=n;++i) scanf("%d",a+i),sum[i]=sum[i-]+a[i];
if (sum[n]!=lowbit(sum[n])) {printf("no\n"); continue;}
for (int i=;i<=n;++i)
{
for (int j=;j<=sum[i];++j)
f[i][j]=-;
for (int j=;j<=sum[i-];++j)
{
if (f[i-][j]==-) continue;
if (lowbit(j)>=a[i]||j==)
{
if (j+a[i]>=highbit[sum[i-]-j]) tmp=;
else tmp=j+a[i];
f[i][tmp]=j;
rec[i][tmp]='l';
}
if (lowbit(sum[i-]-j)>=a[i]||sum[i-]-j==)
{
f[i][j]=j;
rec[i][j]='r';
}
}
}
if (f[n][]==-) printf("no");
else print(n,);
printf("\n");
}
} int get_h()
{
highbit[]=;highbit[]=;
for (int i=;i<=<<;++i)
highbit[i]=highbit[i>>]<<;
} int print(int x,int y)
{
if (x<) return ;
print(x-,f[x][y]);
printf("%c",rec[x][y]);
}

挫挫滴代码

【noip模拟】2048的更多相关文章

  1. android 模拟2048

    利用节日休息时间在ANDROID上进行学习并模拟2048游戏. 效果如下图: 制作思路: 1.画出2048游戏主界面,根据手机屏幕宽高度进行计算并画出每个方块的大小. @Override protec ...

  2. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  3. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  4. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  5. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  6. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  7. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  8. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

  9. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

  10. CH Round #52 - Thinking Bear #1 (NOIP模拟赛)

    A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...

随机推荐

  1. [poj3565]Ants

    [poj3565]Ants 标签(空格分隔):二分图 描述 Young naturalist Bill studies ants in school. His ants feed on plant-l ...

  2. 五分钟了解Hash算法

    Hash算法详解 想象一下如果高级语言(Java,C++ ,C#)中如果没有实现类似List.Map等数据结构,企业级应用开发将是多么痛苦的事吧? Key-Value这种数据结构对于数据处理非常方便. ...

  3. github的拉取、提交,创建分支与合并

    前期准备: 1.安装git  官网地址:https://git-scm.com/(下载下来,直接下一步)   2.github账号(这有点废话)   3.配置github密钥 下载及安装好git后,右 ...

  4. QWebSocket 客户端

    QWebSocket 客户端 Public Function - QWebSocket(const QString &origin = QString(),QWebSocketProtocol ...

  5. Go语言内存管理(一)内存分配

    Go语言内存管理(一)内存分配 golang作为一种"高级语言",也提供了自己的内存管理机制.这样一方面可以简化编码的流程,降低因内存使用导致出现问题的频率(C语言使用者尤其是初学 ...

  6. 安装CentOS7

    安装环境:虚拟机*1 使用软件:CentOS7镜像*1 安装过程: 虚拟机配置步骤(主要部分): 1.安装为Linux:CentOS 64位 2.分配1G内存(若需求大可根据实际情况分配) 3.分配4 ...

  7. “大话架构”阿里架构师分享的Java程序员需要突破的技术要点

    一.源码分析 源码分析是一种临界知识,掌握了这种临界知识,能不变应万变,源码分析对于很多人来说很枯燥,生涩难懂. 源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 我认为是阅读源码的最核心 ...

  8. 【linux】linux下能ping通ip 但是不能ping通域名

    经过一翻查找后解决了,原因和方法如下: [root@~]# grep host /etc/nsswitch.conf#hosts: db files nisplus nis dnshosts:     ...

  9. Xenu-web开发死链接检测工具应用

    Xenu 是一款深受业界好评,并被广泛使用的死链接检测工具. 时常检测网站并排除死链接,对网站的SEO 非常重要,因为大量死链接存在会降低用户和搜索引擎对网站的信任,web程序开发人员还可通过其找到死 ...

  10. JS原生代码实现导航高亮

    一 实现原理 根据当前页面滚动条的高度判断当前页面应当与导航栏中哪个导航相关联,并对相应的导航设置高亮样式. 二 代码解析 先简单写一个页面顶端的导航栏:<nav>  <ul> ...