蓝桥杯31天冲刺打卡(day29)

目录

1、饮料换购(15年省赛)

2、密文搜索(15年国赛)

3、蓝桥骑士​


1、饮料换购(15年省赛)

 简单模拟题

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define MOD 1000000009
using namespace std;
typedef long long LL;
int n,s; 

int main() {
	cin>>n;
	int nn=n;
	while(n>=3) {
		s++;
		n-=2;
	}
	cout<<s+nn;
	return 0;
}


2、密文搜索(15年国赛)

 

标签是数学题,可是我更偏向于是模拟题兼一点排序成分。

资料的顺序不能改变,密码的顺序是打乱的,那么我们就直接使用sort将这些密码一次性排个序,然后用map来存值,最后将实际的密码和可能是密码的密码进行比对算出匹配次数的总和

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define MOD 1000000009
using namespace std;
typedef long long LL;
string s,s1;
int n;
LL ans;
map<string,int> mp;
int main() {
	cin>>s;
	//给定的资料的顺序不能改变,最后的密码当然是后八位啦 
	for(int i=0; i+7<s.size(); i++) {
		string s2;
		for(int j=i; j<=i+7; j++)//每次要8个字母当密码 
		s2+=s[j];//将密码放到变量中来存值 
		sort(s2.begin(),s2.end());//将可能出现的密码进行排序用于后续存储 
		mp[s2]++;//利用map的性质来对可能出现的密码进行存值 
	}
	cin>>n;
	while(n--) {
		cin>>s1;
		sort(s1.begin(),s1.end());//密码是打乱的,需要排一下序 
		ans+=mp[s1];
	}
	cout<<ans;
	return 0;
}

3、蓝桥骑士

解析:

        这是一道LIS(最长上升子序列)模板题,毫无疑问,我们会和LCS联想在一起,也就是说我们会使用DP来做,但是DP的时间复杂度是O(n^2),在这里是9*10^10,超时,所以这道题不能用dp做。

        我们应该用二分+贪心来做,由于它只需要我们求最长上升子序列长度,而非具体元素,那么我们就可以用一个low数组来进行维护,博主刚学最长上升子序列,不知如何表达.详情请看

        下面有DP和二分贪心做法

/*O(n^2)朴素做法 
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define MOD 1000000009
using namespace std;
typedef long long LL;
LL f[300010],n;
LL a[300010],maxn;
int main() {
	cin>>n;
	for(int i=1; i<=n; i++) {
		cin>>a[i];
		f[i]=1;
	}
	for(int i=1; i<=n; i++)
	for(int j=1; j<i; j++) {
		if(a[i]>a[j]) f[i]=max(f[i],f[j]+1);
	}
	for(int i=1; i<=n; i++)
	maxn=max(maxn,f[i]);
	cout<<maxn;
	return 0;
}*/

//二分+贪心
//low序列并不一定表示最长上升子序列,它只表示相应最长子序列长度的排好序的最小序列 
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define MOD 1000000009
using namespace std;
typedef long long LL;
int low[300010],a[300010];
int n,ans; 
int main() {
	cin>>n;
	for(int i=1; i<=n; i++) {
		cin>>a[i];
		low[i]=INF;
	} 
	low[1]=a[1];//初始化第一个数
	ans=1; 
	for(int i=2; i<=n; i++) {
		if(a[i]>low[ans]) //大于就在low中增加
		low[++ans]=a[i];//进low数组
		else {
			//lower_bound找到的点的位置是low+x,即low中第x个位置 
			int j=lower_bound(low+1,low+ans+n,a[i])-low; 
			low[j]=a[i];//和大于等于a[i]的第一个元素的位置互换 
		} 
	}
	cout<<ans; 
	return 0;
}

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_谦言万语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值