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的主要内容,如果未能解决你的问题,请参考以下文章