A. [语言月赛 202401] 装满葡萄汁的酒杯 - 洛谷
题意:有五个容量分别为100,150,300,400,1000的酒杯,输入一个整数n,输出能装下n的最下的酒杯容量(保证n<=1000)
思路:贪心,数组从小到大排序,从小到大遍历,大于等于n就输出
代码:
#include<bits/stdc++.h>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5+10;
int n, m, k;
int a[5]={100,150,300,400,1000};
void sovle(){
cin>>n;
for(int i=0;i<5;i++){
if(a[i]>=n){
cout<<a[i];
return;
}
}
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(0),cout.tie(0);
int t = 1;
//cin>>t;
while (t --){
sovle();
}
return 0;
}
B. [蓝桥杯 2018 省 A] 航班时间 - 洛谷
题意:给出往返程的起飞和降落时间(如果后面有(+x),代表经过了x天),输出两地的飞行时间(如果有则带上时差,即往返程时长不一样)。
思路:用scanf读入更方便(因为奇葩的蓝桥杯数据),如果读入完时间后的下一个getchar读取到的是空格,说明有经过x天,用scanf("(+%d)",&x)来读取。实际上无论有没有时差,都输出往返时间的和/2都能得到正确答案
代码:
#include<bits/stdc++.h>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5+10;
int n;
void sovle(){
int m=0, k=0,a,a1,b,b1,c,c1,d,d1,e,e1,f,f1;
scanf("%d:%d:%d %d:%d:%d",&a,&b,&c,&d,&e,&f);
if(getchar()==' '){
scanf("(+%d)",&m);
}
m*=24;
int sum=(d+m-a)*3600+(e-b)*60+(f-c);
scanf("%d:%d:%d %d:%d:%d",&a1,&b1,&c1,&d1,&e1,&f1);
if(getchar()==' '){
scanf("(+%d)",&k);
}
k*=24;
int num=(d1-a1+k)*3600+(e1-b1)*60+(f1-c1);
int qum=(sum+num)/2;
printf("%02d:%02d:%02d\n",qum/3600,qum%3600/60,qum%3600%60);
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(0),cout.tie(0);
int t = 1;
cin>>t;
//getchar();
while (t --){
sovle();
}
return 0;
}
C. [语言月赛 202312] 铅球杯 - 洛谷
题意:给出n个人的id和值,k个字符串,如果有{?},则将{?}替换成id为?的值,最后输出字符串
思路:用一个结构体数组存入id和值,遍历字符串到{时,建一个新字符串w,不等于}时就w.push_back(),结束后遍历数组找到id为w的输出其值
赛时RE了,因为初始化结构体爆了(悲
更优的思路:用find和replace函数来查找和替换
replace函数用法:
代码:
#include<bits/stdc++.h>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5+10;
int n, m, k;
struct node{
string name;
int num;
}a[5005];
void sovle(){
cin>>n>>m;
//memset(a,0,sizeof(a));
for(int i=0;i<n;i++){
cin>>a[i].name>>a[i].num;
}
getchar();
string s;
for(int i=0;i<m;i++){
getline(cin,s);
for(int j=0;j<s.size();j++){
if(s[j]=='{'){
string q;
j++;
while(s[j]!='}'){
q.push_back(s[j]);
j++;
}
for(int k=0;k<n;k++){
if(q==a[k].name){
cout<<a[k].num;
break;
}
}
}
else cout<<s[j];
}
cout<<endl;
}
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(0),cout.tie(0);
int t = 1;
//cin>>t;
while (t --){
sovle();
}
return 0;
}
优化版:
#include<bits/stdc++.h>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5+10;
int n,m;
map<string,string>v;
void sovle(){
cin>>n>>m;
for(int i=0;i<n;i++){
string a,b;
cin>>a>>b;
v["{"+a+"}"]=b;
}
getchar();
for(int j=0;j<m;j++){
string s;
getline(cin,s);
for(const auto &[a,b]:v)
while (s.find(a) != string::npos)
s.replace(s.find(a),a.size(),b);
cout<<s<<endl;
}
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(0),cout.tie(0);
int t = 1;
//cin>>t;
//getchar();
while (t --){
sovle();
}
return 0;
}
D. [蓝桥杯 2023 省 B] 飞机降落 - 洛谷
题意:给出n架飞机的到达时间,可盘旋时间,降落所需时间。每一时刻最多只能有一架飞机在进行降落。请你输出YES或NO表示能否给出一个降落顺序方案让所有飞机安全降落
思路:数据非常小,可以暴力dfs枚举降落方案能否满足,时间复杂度(10*10!)。
对于方案能否成功,关键在于前一架飞机尽快落地,后一架飞机才能有更多的时间落地。
贪心地,如果前一架飞机到达时间+落地时间<=当前飞机的到达时间+盘旋时间,那么当前飞机就能降落,并且当前飞机的到达时间应该更新为max(前一架飞机到达时间+落地时间,当前飞机的到达时间),这样每一次都判断,有一个不符合就输出NO,都符合就输出YES
代码:
#include<bits/stdc++.h>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5+10;
int n,m;
bool b[15];
struct node{
int t,d,l;
}a[15];
bool dfs(int x,int time){
if(x>=n){
return true;
}
for(int i=0;i<n;i++){
if(!b[i]){
b[i]=1;
if(a[i].t+a[i].d<time){
b[i]=0;
return false;
}
int t=max(a[i].t,time)+a[i].l;
if(dfs(x+1,t)){
return true;
}
b[i]=0;
}
}
return false;
}
void sovle(){
cin>>n;
memset(b,0,sizeof(b));
for(int i=0;i<n;i++){
cin>>a[i].t>>a[i].d>>a[i].l;
}
if(dfs(0,0)){
cout<<"YES"<<endl;
}
else cout<<"NO"<<endl;
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(0),cout.tie(0);
int t = 1;
cin>>t;
//getchar();
while (t --){
sovle();
}
return 0;
}
E. [蓝桥杯 2023 省 B] 接龙数列 - 洛谷
题意:对于一个整数数列,如果每个数的首位都等于上一个数的末位,则称该数列为接龙数列
(i>=2&&i<=n)。输入一个长度为n数列,询问最少要删除几个数才能使该数列成为接龙数列
思路:数据太大10^5,暴力做法会超时。考虑用线性dp的方法,dp[i]表示以i结尾的接龙数列的长度,状态转移方程:dp[u]=max(dp[x],dp[u]+1),x表示该数的首位,u表示该数的末位。
代码:
#include<bits/stdc++.h>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5+10;
int n,m,dp[10];
void sovle(){
cin>>n;
for(int i=0;i<n;i++){
string s;
cin>>s;
dp[s[s.size()-1]-'0']=max(dp[s[s.size()-1]-'0'],dp[s[0]-'0']+1);
}
int max1=0;
for(int i=0;i<=9;i++){
max1=max(dp[i],max1);
}
cout<<n-max1;
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(0),cout.tie(0);
int t = 1;
//cin>>t;
//getchar();
while (t --){
sovle();
}
return 0;
}
F. [蓝桥杯 2018 国 B] 调手表 - 洛谷
题意:一个小时有n分钟,每次可以选择让当前时间增加1或者k分钟,询问调到其他分钟最多需要操作多少次(分钟大于等于n时%n)
思路:bfs搜索到达所有时间需要多少层,如果已经访问过的时间就剪枝掉。头疼在怎么表示在第几层。可以用一个数组b[i]表示到达i这个时间的层数,每次搜索都step让step=b[i],b[(i+1)%n]=b[i]+1(下一层),b[(i+m)%n]=b[i]+1
代码:
#include<bits/stdc++.h>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5+10;
int n, m, k,max1,step,b[100005];
bool a[100005];
int bfs(int x){
int sum=0;
int u=0,w=0;
a[x]=1;
int step=1;
queue<int>v;
v.push(x);
while(!v.empty()&&sum!=n-1){
int i=v.front();
v.pop();
step=b[i];
if(!a[(i+1)%n]){
a[(i+1)%n]=1;
b[(i+1)%n]=b[i]+1;
v.push((i+1)%n);
}
if(!a[(i+m)%n]){
a[(i+m)%n]=1;
b[(i+m)%n]=b[i]+1;
v.push((i+m)%n);
}
}
return step;
}
void sovle(){
cin>>n>>m;
max1=max(max1,bfs(0));
cout<<max1;
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0),cout.tie(0);
int t = 1;
//cin>>t;
while (t --){
sovle();
}
return 0;
}
G. [蓝桥杯 2023 省 A] 更小的数 - 洛谷
题意:输入一个只含数字的字符串,可以选择任意长度的子字符串num翻转为num1,如果num>num1,则答案数+1,输出答案总数
思路:区间dp,dp[l][r]表示下标l-r的子字符串能否满足条件,如果s[l]<s[r],dp[l][r]=1
如果s[l]==s[r],dp[l][r]=dp[l+1][r-1],如果s[l]>s[r],dp[l][r]=0
为了更新状态,需要从最后开始选取子串
代码:
#include<bits/stdc++.h>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5+10;
int n, m, k,max1,step,dp[5005][5005],sum;
void sovle(){
string s;
cin>>s;
for(int i=s.size()-1;i>=0;i--){
for(int j=i;j<s.size();j++){
//if(j==i) continue;
if(s[j]<s[i]) dp[i][j]=1;
else if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1];
else dp[i][j]=0;
if(dp[i][j]){
sum++;
}
}
}
cout<<sum;
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0),cout.tie(0);
int t = 1;
//cin>>t;
while (t --){
sovle();
}
return 0;
}