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);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一份可能的蓝桥杯赛前训练计划: 1. 熟悉考试内容和题型:了解蓝桥杯考试的内容和题型,包括编程语言、数据结构与算法、计算机基础知识和实践能力等方面的内容,并准备相关资料和练习题目。 2. 制定学习计划:根据自己的水平和时间安排,制定一份具体的学习计划,包括每天的学习目标、练习时间和计划完成时间等,以保证充分利用时间进行学习和练习。 3. 提高编程能力:进行编程练习,提高编程能力,特别是数据结构和算法的实践能力。可以参加在线编程竞赛、练习题目和刷题等方式来提高编程能力。 4. 提高计算机基础知识:学习计算机基础知识,包括计算机组成原理、操作系统、计算机网络、数据库等方面的知识,以提高程序的效率和优化能力。 5. 实践能力:进行实践练习,包括操作系统和网络配置、数据库设计和开发、Web开发等方面的实践,以提高实践能力和解决问题的能力。 6. 团队协作:参加团队协作项目,锻炼团队合作和沟通能力,同时学习项目管理和软件开发流程等相关知识。 7. 模拟考试:进行模拟考试,以检验自己的学习成果和考试准备情况,同时找出自己的弱点和不足,加以改进和提高。 8. 调整状态:保持良好的身体状态和心态,保证充足的睡眠和饮食,调整好心态,保持积极向上的心态。 以上是一份可能的蓝桥杯赛前训练计划,具体的训练计划需要根据个人情况和水平来制定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值