• (模拟+贪心)codeforces


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


    分析:

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

    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
    ",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 }
  • 相关阅读:
    UVA
    [CQOI2018] 社交网络
    UVA
    51nod 1314 定位系统
    51nod 1211 数独
    51nod 1392 装盒子
    51nod1253 Kundu and Tree
    51nod1313 完美串
    51nod1039 x^3 mod p
    51nod1369 无穷印章
  • 原文地址:https://www.cnblogs.com/tak-fate/p/6021603.html
Copyright © 2020-2023  润新知