21-22-1蓝桥训练9

Posted 斗奋力努

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了21-22-1蓝桥训练9相关的知识,希望对你有一定的参考价值。

21-22-1蓝桥训练9

补充本周蓝桥CE两题。

题目
C、试题 算法提高 合并石子
思路:
本题是区间dp的经典例题,当然石子合并问题还有很多的变化,也有一些神奇的优化方法,有兴趣的大佬可以自己去学习一下(这里我给出连接:石子合并问题–动态规划;贪心)

这里我用的是(GarsiaWachs算法)

#include <fstream>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N = 50005;
const int INF = 0x3f3f3f3f;

int stone[N];
int n,t,ans;
void combine(int k)

    int tmp = stone[k] + stone[k-1];
    ans += tmp;
    t--;
    for(int i=k;i<t;i++)
        stone[i] = stone[i+1];
    int j = 0;
    for(j=k-1;stone[j-1] < tmp;j--)
        stone[j] = stone[j-1];
    stone[j] = tmp;
    while(j >= 2 && stone[j] >= stone[j-2])
    
        int d = t - j;
        combine(j-1);
        j = t - d;
    
 
int main()

     scanf("%d",&n);
         for(int i=1;i<=n;i++)
             scanf("%d",&stone[i]);
         stone[0]=INF;
         stone[n+1]=INF-1;
         t = 3;
         ans = 0;
        for(int i=3;i<=n+1;i++)
        
             stone[t++] = stone[i];
             while(stone[t-3] <= stone[t-1])
                 combine(t-2);
         
         while(t > 3) combine(t-1);
         printf("%d\\n",ans);
         memset(stone,0,sizeof(stone));
     return 0;
   

E、试题 算法提高 Intersecting Dates
题意:
简单的说,已知nx个时间区间中的每一天,但是要求知道nr个时间区间中的每一天,问需要
新增出几个时间区间,才能到达要求。
如果时间区间只有一天的话,输出该天时间即可,格式:** 月/日/年**(前面四个空格)
否则输出区间开始时间和结束时间。格式** 月/日/年 to 月/日/年**(前面四个空格,第一个月/日/年是开始时间,第二个月/日/年是结束时间)
要是没有新增时间区间,输出** No additional quotes are required.**(前面四个空格)

思路:
直接模拟就行了,我们可以将1700年到2100年中的每一天按顺序转化成数字,然后先记录一下已知区间,随后在读入要求区间的时间将区间对应的每一个数字标记一下,之后再用已知区间将可以消除标记的数字全部删除。最后仍然处于标记状态的数字就是要新增的时间。
同时,我们通过全局变量flag来判断是否有新增区间,没有就输出** No additional quotes are required.**,
两个小细节:
①:每次我们都应该初始化flag和对标记数组vis进行清空。
②:每次询问后要多输出一次换行,不然过不了全部数据。(根据红色框框得出)

#include<bits/stdc++.h>
using namespace std;
const int N=105;
int t,nx,nr;
int st[N],ed[N];
bool flag;
int days[]=0,31,28,31,30,31,30,31,31,30,31,30,31;
bool vis[150000]; //400*366=146400

bool cek(int x)return (x%4==0&&x%100!=0)||(x%400==0);

int change(int x)
    int year=x/10000;
    int month=(x%10000)/100;
    int day=x%100;
    int sum=0;
    for(int i=1700;i<year;i++)
        if(cek(i)) sum+=366;
        else sum+=365;
    
    if(cek(year)) days[2]=29;
    else days[2]=28;
    for(int i=1;i<month;i++) sum+=days[i];
    sum+=day;
    return sum;


void get_vis(int start,int end,int type)
    int st1=change(start);
    int ed1=change(end);
    for(int i=st1;i<=ed1;i++) vis[i]=type;


void change1(int x,bool kind)
    int year=1700,month=0,day=0,hv=0,te;
    while(1)
        if(cek(year)) te=366;
        else te=365;
        if(hv+te>x) break;
        year++,hv+=te; 
    

    if(hv==x)
        year--;
        month=12;
        day=31;
    
    else
        if(cek(year)) days[2]=29;
        else days[2]=28;
        for(int i=1;i<=12;i++)
            if(hv+days[i]>x) break;
            month++,hv+=days[i];
        
        if(hv==x) day=days[month];
        else month++,day=x-hv;
        // if(hv==x) day=days[month];
        // else day=x-hv;
    
    printf("%d/%d/%d",month,day,year);
    if(kind) puts("");


void solve(int ci)
    printf("Case %d:\\n",ci);
    for(int i=1;i<150000;i++) vis[i]=false;
    for(int i=1;i<=nx;i++) scanf("%d%d",&st[i],&ed[i]);
    for(int i=1;i<=nr;i++)
        int start,end; scanf("%d%d",&start,&end);
        get_vis(start,end,1);
    
    for(int i=1;i<=nx;i++) get_vis(st[i],ed[i],0);
    for(int i=1;i<150000;i++)
        if(vis[i])
            flag=true;
            printf("    ");
            if(!vis[i+1]) change1(i,true);
            else
                change1(i,false);
                printf(" to ");
                for(int j=i+1;j<150000;j++)
                   // cout<<"j="<<j<<"\\n";
                    if(vis[j]) continue;
                    else change1(j-1,true);i=j-1;break;
                
            
        
    
    if(!flag) puts("    No additional quotes are required.");
    puts("");


int main()
    while(scanf("%d%d",&nx,&nr))
        if(nx==0&&nr==0) return 0;
        t++; flag=false;
        solve(t);
    


以上是关于21-22-1蓝桥训练9的主要内容,如果未能解决你的问题,请参考以下文章

2021-11-12--《21-22-1蓝桥训练6》

21-22-1蓝桥训练1

2021.12.10--《21-22-1蓝桥训练8》

2021.10.22--《21-22-1蓝桥训练3》

2021.10.29--《21-22-1蓝桥训练4》

21-22-1蓝桥训练4