(模拟+贪心)codeforces - 733C Epidemic in Monstropolis

题意:有一排数字,大的数字向左或者向右吃相邻的比它小的数字,问能不能吃成另一个数列。



分析:

稍微想一下,可以感觉得到,新数列的每个数字都是由一段连续的原数列子数列相互吃成的,并且这些子数列也是从头连续的相连的,进而组成的原数列。比如

a[0] [1] [2] [3] [4]

b[0] [1]

如果b[0]==a[0]+a[1]+a[2],那么b[0]就是a[0-2]吃成的。

那么如果YES,必然b[1]==a[3]+a[4],也就是b[1]是由a[3-4]吃成的。

所以只需要先找出满足的子数列,在寻找的过程中,找出满足条件的每个子数列,再分别再每个子数列中选择最大的向左向右吃贪心。

但是NO有很多坑点:

1、a前面的几个数已经匹配完了b中所有的数,且a还有剩余,必然NO(在这WA了2发)

2、单独的一个匹配(子数列中每个数一样大当且仅当子数列的长度大于1,才能是NO)的时候应该是YES

这题好坑啊,WA了五六发。。。曹。。



代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <string>
  4 #include <vector>
  5 #include <map>
  6 #include <set>
  7 #include <queue>
  8 #include <cstring>
  9 #include <algorithm>
 10
 11 using namespace std;
 12
 13
 14 typedef long long ll;
 15 typedef unsigned long long ull;
 16 #define inf (0x3f3f3f3f)
 17 #define lnf (0x3f3f3f3f3f3f3f3f)
 18 #define eps (1e-8)
 19 int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1 ;}
 20
 21 //-------------------------------------------------
 22
 23 const int maxn=510;
 24 int an[maxn],bn[maxn];
 25 vector<int> v[maxn];
 26
 27 char ac[maxn];
 28 int  as[maxn];
 29
 30 void solve(){
 31     int a,b;
 32     scanf("%d",&a);
 33     for(int i=0;i<a;i++){
 34         scanf("%d",&an[i]);
 35     }
 36     scanf("%d",&b);
 37     for(int i=0;i<b;i++){
 38         scanf("%d",&bn[i]);
 39     }
 40     int cnt=0;
 41     int res=0;
 42     int st=0;
 43     for(int i=0,j=0;i<b,j<a;j++){
 44         res+=an[j];
 45         if(res==bn[i]){
 46             for(int k=st;k<=j;k++){
 47                 v[cnt].push_back(an[k]);
 48             }
 49             cnt++;
 50             st=j+1;
 51             res=0;
 52             i++;
 53         }
 54         if(cnt==b&&j<a-1){
 55             puts("NO");
 56             return;
 57         }
 58     }
 59     if(cnt!=b){
 60         puts("NO");
 61         return;
 62     }
 63     int num=0;
 64     for(int i=0;i<cnt;i++){
 65         int maxs=-1;
 66         int site;
 67         for(int j=0;j<v[i].size();j++){
 68             if(j==0){
 69                 if(v[i][j]>maxs&&v[i][j+1]<v[i][j]){
 70                     maxs=v[i][j];
 71                     site=j;
 72                 }
 73             }
 74             else if(j==v[i].size()-1){
 75                 if(v[i][j]>maxs&&v[i][j-1]<v[i][j]){
 76                     maxs=v[i][j];
 77                     site=j;
 78                 }
 79             }
 80             else{
 81                 if(v[i][j]>maxs&&(v[i][j]>v[i][j-1]||v[i][j]>v[i][j+1])){
 82                     maxs=v[i][j];
 83                     site=j;
 84                 }
 85             }
 86         }
 87         if(maxs==-1&&v[i].size()>1){
 88             puts("NO");
 89             return;
 90         }
 91         int si=v[i].size();
 92         while(si>1){
 93             if(site==0){
 94                 if(v[i][site]>v[i][site+1]){
 95                     ac[num]=‘R‘;
 96                     as[num++]=site+i;
 97                     for(int j=site+2;j<si;j++){
 98                         v[i-1]=v[i];
 99                     }
100                     v[i][site]+=v[i][site+1];
101                     si--;
102                 }
103             }
104             else if(site==si-1){
105                 if(v[i][site]>v[i][site-1]){
106                     ac[num]=‘L‘;
107                     as[num++]=site+i;
108                     site--;
109                     v[i][site]+=v[i][site+1];
110                     si--;
111                 }
112             }
113             else{
114                 if(v[i][site]>v[i][site+1]){
115                     ac[num]=‘R‘;
116                     as[num++]=site+i;
117                     for(int j=site+2;j<si;j++){
118                         v[i-1]=v[i];
119                     }
120                     v[i][site]+=v[i][site+1];
121                     si--;
122                 }
123                 else if(v[i][site]>v[i][site-1]){
124                     ac[num]=‘L‘;
125                     as[num++]=site+i;
126                     site--;
127                     v[i][site]+=v[i][site+1];
128                     si--;
129                 }
130             }
131         }
132
133     }
134     puts("YES");
135     for(int i=0;i<num;i++){
136         printf("%d %c\n",as[i]+1,ac[i] );
137     }
138
139
140
141 }
142
143
144
145 int main(){
146
147 #ifndef ONLINE_JUDGE
148     freopen("1.in","r",stdin);
149     //freopen("1.out","w",stdout);
150 #endif
151
152     solve();
153 }
时间: 2024-10-13 11:32:35

(模拟+贪心)codeforces - 733C Epidemic in Monstropolis的相关文章

CodeForces 733C Epidemic in Monstropolis

模拟. 连续的一段$a$合成一个$b$.每段中如果数字只有$1$个,那么可以合成.如果数字个数大于等于$2$个,如果都是一样的,那么无法合成,否则要找到一个可以移动的最大值位置开始移动.一开始写了一个模拟,没考虑到严格大于,$WA$在$106$组数据了...... #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include&

HDU 4903 (模拟+贪心)

Fighting the Landlords Problem Description Fighting the Landlords is a card game which has been a heat for years in China. The game goes with the 54 poker cards for 3 players, where the “Landlord” has 20 cards and the other two (the “Farmers”) have 1

【模拟】Codeforces 707A Brain&#39;s Photos

题目链接: http://codeforces.com/problemset/problem/707/A 题目大意: 给一张N*M的图,只有六种颜色(如下),只含B,W,G的是黑白图,否则是彩色图.问这张图是什么图. 'C' (cyan) 'M' (magenta) 'Y' (yellow) 'W' (white) 'G' (grey) 'B' (black) 题目思路: [模拟] 签到题.直接mark记一下是否出现彩色即可. 1 // 2 //by coolxxx 3 //#include<b

UVA-11054-Wine trading in Gergovia(模拟+贪心)

首先这道题的节点数太多了,达到10^5,所以不能用数组模拟啊,肯定TLE,所以用贪心算法,读取第一个结点,搬到第二个结点,剩下的和第二个结点合并,一起搬到第三个结点......这个算法很好,每次看成只是邻居间买卖,下面是代码: #include<stdio.h> #include<iostream> #include<stdlib.h> using namespace std; int main() { int n; while(cin>>n &&a

Codeforces 452D [模拟][贪心]

题意: 给你k件衣服处理,告诉你洗衣机烘干机折叠机的数量,和它们处理一件衣服的时间,要求一件衣服在洗完之后必须立刻烘干,烘干之后必须立刻折叠,问所需的最小时间. 思路: 1.按照时间模拟 2.若洗完的衣服或者烘干的衣服较多来不及进行下一个步骤,则从一开始就顺延洗衣服的时间,贪心的思想也是体现在这里. 3.关键在于烘干衣服的顺延如何处理,因为需要调整洗衣服的起始时间,其实我们只要对烘干衣服的时间进行顺延处理就可以了,因为即使没有调整洗衣服的起始时间,那么下次到了烘干衣服的时间的时候因为烘干衣服的数

Codeforces 534D Handshakes 构造 模拟 贪心

题意:人们依次进大厅,后进来的人会和里面所有的人都握手, 大厅里面有三个人就 其中丧二恩就可以结伴走出大厅.给你每个人进大厅时候握手的次数.让你求一个进场顺序. 解题思路:比赛的时候是用的从后往前推.比较难,发现从前往后直接模拟就行了 . 解题代码: 1 // File Name: d.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月13日 星期一 01时30分17秒 4 5 #include<vector> 6 #include&l

CodeForces 825B(模拟&amp;贪心_D题)解题报告

题目链接:http://codeforces.com/problemset/problem/825/B -------------------------------------------------------------------------------- 题意:五子棋,在输入条件下,能否在当前局面获胜. 思路:很明显的是,当我们下五子棋时,我们每步都是进行一次搜索,观察能否连接成为5个.同理,利用计算机也可以向各个方向进行搜索.好在本题只是10X10的棋面,直接对每个点进行4个方向(水

【模拟】Codeforces 706A Beru-taxi

题目链接: http://codeforces.com/problemset/problem/706/A 题目大意: 家的坐标在sx,sy,有n辆车,每辆车坐标xi,yi,速度vi,问最快的一辆车什么时候到家. 题目思路: [模拟] 签到题. 1 // 2 //by coolxxx 3 // 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8

【模拟】Codeforces 691B s-palindrome

题目链接: http://codeforces.com/problemset/problem/691/B 题目大意: 求一个字符串是不是镜像的(不是回文).是输出TAK否则RE. 题目思路: [模拟] 预处理镜像的字母,注意bd pq,从头尾开始模拟. 1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<strin