题意

现在有一个怪兽序列a[i],权值大的怪兽可以吃权值小的怪兽,吃完之后权值大的怪兽的权值会变成两者权值的和,相邻的怪兽才能吃

吃完之后,位置合并,队列前移,从左到右重新编号,重复这一过程,

然后给你一个怪兽序列b[i],问你a[i]怎么操作能变成b[i],如果能操作,输出操作序列,如果不能操作就输出NO

难点一,划分序列,由于b[i]的概念类似于前缀和,一旦b[i]是确定的数,那么a[i]序列的划分就是唯一的,b[i]和a[i]的和相等

b[i]序列实际上就是对序列a[i]的唯一划分

难点二,如何判定由b[i]划分的小区间一定能全部合并?我们的办法是,找最容易满足的条件,如果你能养起来尽可能大的怪兽

,一旦它成为了最大值,那么这个小区间一定是可以合并的,这个贪心策略看起来是显然的(笑,所以我们每次尽量合成最大的怪兽

如果这样都合并不了整个区间,那么这个区间一定是不可合并的,我表示不会严格数学证明

难点三,如果用数组这个数据结构,我发现合并这个操作,我完全不知道怎么写,加上vis数组?哪个被合并就哪个记为被访问?

那么我们每次要找到两个没有被访问且连续的元素然后合并权值,操作vis,也不是不行,我觉得这个写法太tm恶心了

我选择用链表,权值用a[i]存,nxt[i]存储每个元素的下一跳,合并操作就变成了连跳操作,nxt[i]=nxt[nxt[i]],

但是对于数序号来说,我们要另外写一个函数来O(n),获取该元素的rank,还好n比较小

难点三、输出最终的答案序列

我用了vector,和结构体存储了位置了操作字符,不是很简单,有机会去看看大神们是怎么写的

难点四、考虑b[i]序列是否是合法序列,少考虑了两种,这个太致命了,一开始我是有想法的,后来忘了填坑了,以后觉得不放心的

地方都要加一个注释才行,具体坑点详见代码

难点五、注意合并操作的更新位置,要想记录当前操作,需要先记录再更新,更新后再记录就是错的了,不是我们想要的信息

#include <cstdio>
#include <vector>
#define ll long long
const int maxn=;
int n,k;
int a[maxn],b[maxn],flag[maxn];
int nxt[maxn];
struct node{
int pos;
char type;
//0 left 1 right
};//结构体后面忘了加分号
std::vector<node> ans;
void init(int left,int right){
register int i;
for(i=left;i<right;++i){
nxt[i]=i+;
}
nxt[right]=-;
}
bool check(int left,int right){
if(nxt[left]!=-) return false;
return true;
}
int findIndex(int left,int index){
int cnt=;
register int i;
for(i=left;i!=-;i=nxt[i]){
cnt++;
if(index==i){
return cnt;
}
}
return -;
//error
}
int solve(int left,int right,int pre){
ll mx=-;
int index,first=;
register int i;
for(i=left;i!=-;i=nxt[i]){
if(nxt[i]!=-&&a[i]!=a[nxt[i]]){
if(first){
first=;
mx=a[i]+a[nxt[i]];
index=i;
}
else{
ll temp=a[i]+a[nxt[i]];
if(temp>mx){
mx=temp;
index=i;
}
}
}
}
if(mx!=-){
int pos1=findIndex(left,index);
int pos2=findIndex(left,nxt[index]);
if(a[index]>a[nxt[index]]){
ans.push_back((node){pre+pos1,'R'});
}
else{
ans.push_back((node){pre+pos2,'L'});
}
a[index]+=a[nxt[index]];//这两句话位置不对,之前做的早了
nxt[index]=nxt[nxt[index]];
}
return mx;
}
int main(){
scanf("%d",&n);
register int i;
ll suma=,sumb=;
for(i=;i<n;++i){
scanf("%d",a+i);
suma+=a[i];
}
scanf("%d",&k);
for(i=;i<k;++i){
scanf("%d",b+i);
sumb+=b[i];
}
if(suma!=sumb) {
printf("NO\n");
return ;
}
ll temp=;
int cur=,cnt=;
for(i=;i<n;++i){
temp+=a[i];
if(temp==b[cur]){
flag[cnt++]=i;
++cur;
temp=;
}
else if(temp>b[cur]){
printf("NO\n");//NO 打成 No
return ;
}
}
if(cur!=k) {
printf("NO\n");
return ;
}
register int j;
int No=;
for(i=;i<cnt;++i){
int left,right=flag[i];
if(i==){
left=;
}
else{
left=flag[i-]+;
}
init(left,right);
while(!check(left,right)){
int p=solve(left,right,i);
if(p==-){
No=;
break;
}
}
if(No){
break;
}
}
if(No) printf("NO\n");
else{
printf("YES\n");
for(i=;i<ans.size();++i){
node t=ans[i];
printf("%d %c\n",t.pos,t.type);
}
}
return ;
}

codeforces733-C. Epidemic in Monstropolis 贪心加链表的更多相关文章

  1. CF733C Epidemic in Monstropolis[模拟 构造 贪心]

    C. Epidemic in Monstropolis time limit per test 1 second memory limit per test 256 megabytes input s ...

  2. Epidemic in Monstropolis

    Epidemic in Monstropolis 题目链接:http://codeforces.com/contest/733/problem/C 贪心 新序列的m个数肯定是由原序列的连续的m个子序列 ...

  3. 【16.52%】【codeforces 733C】Epidemic in Monstropolis

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  4. Codeforces Round #378 (Div. 2) C. Epidemic in Monstropolis 模拟

    C. Epidemic in Monstropolis time limit per test 1 second memory limit per test 256 megabytes input s ...

  5. Codeforces Round #378 (Div. 2)-C. Epidemic in Monstropolis

    C. Epidemic in Monstropolis time limit per test 1 second memory limit per test 256 megabytes input s ...

  6. Codeforces 733C:Epidemic in Monstropolis(暴力贪心)

    http://codeforces.com/problemset/problem/733/C 题意:给出一个序列的怪兽体积 ai,怪兽只能吃相邻的怪兽,并且只有体积严格大于相邻的怪兽才能吃,吃完之后, ...

  7. BZOJ_2151_种树_贪心+堆+链表

    BZOJ_2151_种树_贪心+堆 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编 ...

  8. [luogu3620][APIO/CTSC 2007]数据备份【贪心+堆+链表】

    题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏 ...

  9. [bzoj2288][pojChallenge]生日礼物【贪心+堆+链表】

    题目描述 ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, -, AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物. 自然地,ftiasch想要知 ...

随机推荐

  1. Solr集群常用的操作总结

    之前搭建过SolrCloud和Solr单机版本,另外还有很多对Solr配置文件以及核心的操作,以下主要总结Solr集群中的常用操作,即在配置文件中正确设置ZK_HOST参数并且Zookeeper正确启 ...

  2. java web 学习 --第八天(Java三级考试)

    第七天的学习内容:http://www.cnblogs.com/tobecrazy/p/3464231.html EL表达式 EL : Expression Language 使用EL表达式可以减少& ...

  3. HDU 4940 Destroy Transportation system(无源汇有上下界最大流)

    看不懂题解以及别人说的集合最多只有一个点..... 然后试了下题解的方法http://blog.sina.com.cn/s/blog_6bddecdc0102uzka.html 首先是无源汇有上下界最 ...

  4. Greedy:Linear world(POJ 2674)

      Linear world 题目大意:一些人生活在线性世界中,到达线性世界两端就会消失,两个人的前进方向有两个,相遇会改变各自相遇方向,求最后一个人掉下的人的名字和时间. 其实这一题就是弹性碰撞的模 ...

  5. Enum:EXTENDED LIGHTS OUT(POJ 1222)

    亮灯 题目大意:有一个5*6的灯组,按一盏灯会让其他上下左右4栈和他自己灯变为原来相反的状态,要怎么按才会把所有的灯都按灭? 3279翻版题目,不多说,另外这一题还可以用其他方法,比如DFS,BFS, ...

  6. 从下拉菜单拖拽一个元素 出来,插入到页面中的app 列表中

    1,实现功能:从下拉菜单拖拽一个元素 出来,插入到页面中的app 列表中 并实现app向后移动一个元素的位置: 2.实现思路: 01.遍历下拉菜单,添加拖拽方法,实现位置移动功能: 02.遍历app列 ...

  7. JPA查询语句(转载)

    JPQL就是一种查询语言,具有与SQL 相类似的特征,JPQL是完全面向对象的,具备继承.多态和关联等特性,和hibernate HQL很相似.   查询语句的参数 JPQL语句支持两种方式的参数定义 ...

  8. Android 支付宝以及微信支付快速接入流程

    简介 随着移动支付的普及,越来越多的App采用第三发支付,在这里我们以支付宝为例,做一个快速集成! 一.Android快速实现支付宝支付 1.首先,我们需要前往支付宝开放平台,申请我们的支付功能:ht ...

  9. 字符串与byte数组转换

    string weclome=""; byte[] data = new byte[1024]; //字符串转byte数组 data = Encoding.ASCII.GetByt ...

  10. 创建DLL、Lib以及使用DLL、Lib

    1.要在生成DLL文件的同时生成Lib文件,函数声明时前面要加__declspec(dllexport). 可在头文件中如下定义: #ifndef __MYDLL_H#define __MYDLL_H ...