2021.10.29--《21-22-1蓝桥训练4》
Posted 斗奋力努
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.10.29--《21-22-1蓝桥训练4》相关的知识,希望对你有一定的参考价值。
2021.10.29–《21-22-1蓝桥训练4》
题目
1、试题 算法训练 字串统计
思路:n的范围才60,直接无脑暴力,枚举所有长度>=m的字符串,找出符合题意的那一个就行了。
#include<bits/stdc++.h>
using namespace std;
int n,mx;
string s,now_s,max_s;
map<string,int>mp;
int main(){
cin>>n>>s;
while(n<s.length()){
for(int i=0;i+n<s.length();i++){
now_s=s.substr(i,n);
mp[now_s]++;
if(mp[now_s]>mx){
mx=mp[now_s];
max_s=now_s;
}
else if(mp[now_s]==mx){
int len1=max_s.length();
int len2=now_s.length();
if(len2>len1){
max_s=now_s;
}
}
}
n++;
}
cout<<max_s<<"\\n";
return 0;
}
2、试题 算法提高 c++_ch06_02
**日常看不懂蓝桥杯的题意 **
思路:
瞎搞吧,这题数据范围都没有,我们用上神器vector来存数组a和b的数据。
然后特判m1与m2的情况就行了。(具体看代码)
注意格式:
1、最后一个输出的元素后面是换行。
2、前面的所有元素,都是先输出元素,再输出一个’,’(英文字符中的逗号),最后还得输出一个空格’ '。
#include<bits/stdc++.h>
using namespace std;
int n,m,m1,m2;
vector<int>a,b;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int x;scanf("%d",&x);
a.push_back(x);
}
for(int i=1;i<=m;i++){
int x;scanf("%d",&x);
b.push_back(x);
}
scanf("%d%d",&m1,&m2);
if(m1==0&&m2==0){
for(int i=0;i<n;i++){
printf("%d",a[i]);
if(i==n-1) printf("\\n");
else printf(", ");
}
}
else if(m1==0){
for(int i=0;i<m2;i++){
printf("%d",b[i]);
if(i==m2-1) printf("\\n");
else printf(", ");
}
}
else if(m2==0){
for(int i=0;i<n;i++){
printf("%d",a[i]);
if(i==n-1) printf("\\n");
else printf(", ");
}
}
else{
for(int i=0;i<m1;i++) printf("%d, ",a[i]);
for(int i=0;i<m2;i++){
printf("%d",b[i]);
if(i==m2-1) printf("\\n");
else printf(", ");
}
}
return 0;
}
3、试题 算法提高 找素数
思路:
1、正常开空间去筛的话,空间肯定开不下。只有一次查询的,所以我们可以在筛的时候让所有数向左移动l,即本来要存在
p
r
i
m
e
[
l
r
]
prime[l~r]
prime[l r]的元素移动到
p
r
i
m
e
[
0
r
−
l
]
prime[0~r-l]
prime[0 r−l],这样我们总空间就只要开2e6,这是开的下的。
2、还剩一个难点,怎么确定素数?我们可以先找到第一个在区间
[
l
,
r
]
[l,r]
[l,r]中素数i的最小倍数,然后将其所以倍数都遍历一次用prime记录,最后统计区间
[
l
,
r
]
[l,r]
[l,r]中没有遍历过的点的个数就是答案。注意此时区间
[
l
,
r
]
[l,r]
[l,r]已经变为prime数组中区间
[
0
,
r
−
l
]
[0,r-l]
[0,r−l]。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e6+6;
bool isprime[N],prime[N];
void prim(ll l,ll r){
for(ll i=2;i<=r/i;i++){
if(!isprime[i]){
for(ll j=i*i;j*j<=r;j+=i) isprime[j]=true;
for(ll j=max(i,(l-1)/i+1)*i;j<=r;j+=i) prime[j-l]=true;
}
}
ll num=0;
for(ll i=0;i<=r-l;i++){
if(!prime[i]) num++;
}
cout<<num<<"\\n";
}
int main(){
ll l,r; cin>>l>>r;
prim(l,r);
return 0;
}
4、试题 算法提高 种树
思路:
数据很小,可以无脑dfs。
1、不符合条件的情况是(n<2*m); 自证不难
2、符合条件的情况。dfs(int pos,int num,int val) 第一个参数是当前位置,第二个参数是当前已经选了多少个坑,第三个参数是当前的价值。
3、能用dfs就用dfs,别递推。
#include<bits/stdc++.h>
using namespace std;
const int N=35;
int n,m,a[N];
int ans;
bool vis[N];
void dfs(int p,int num,int val){
if(num==m){
ans=max(ans,val);
return;
}
if(p>n) return;
if(p==n){//处理第n个坑
if(num==m-1&&!vis[p-1]&&!vis[1]){
ans=max(ans,val+a[p]);
}
return;
}
vis[p]=true;
dfs(p+2,num+1,val+a[p]);
vis[p]=false;
dfs(p+1,num,val);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
if(n<2*m) {puts("Error!");return 0;}
dfs(1,0,0);
printf("%d\\n",ans);
}
5、试题 算法提高 质数的后代
思路:
打一张到1e5的素数表,然后每个去判断是否有符合题意的素数对就行了。不会欧拉筛的同学去自学一下。
疑问:
本题是否可以离线写???
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int prime[N],cnt;
bool vis[N],can[N];
void build(){
for(int i=2;i<=1e5;i++){
if(!vis[i]) prime[++cnt]=i;
for(int j=1;prime[j]<=1e5/i;j++){
vis[i*prime[j]]=true;
if(i%prime[j]==0) break;
}
}
}
bool check(int x){
for(int i=1;i<=cnt;i++){
if(x%prime[i]==0){
int y=x/prime[i];
if(!vis[y]&&(x!=prime[i]&&x!=y)) return true;
}
}
return false;
}
int main(){
build();
int t;scanf("%d",&t);
while(t--){
int x;scanf("%d",&x);
if(check(x)) puts("Yes");
else puts("No");
}
}
6、试题 算法训练 学做菜
思路:
按照题意一路while循环下来就行了。
#include<bits/stdc++.h>
using namespace std;
int a,b,c,d;
int t1=0,t2=0,t3=0,t4=0,t5=0;
int main(){
cin>>a>>b>>c>>d;
while(a>=2&&b>=1&&d>=2){a-=2;b-=1;d-=2;t1++;}
while(a>=1&&b>=1&&c>=1&&d>=1){a--;b--;c--;d--;t2++;}
while(c>=2&&d>=1){c-=2;d--;t3++;}
while(b>=3){b-=3;t4++;}
while(a>=1&&d>=1){a--;d--;t5++;}
cout<<t1<<endl<<t2<<endl<<t3<<endl<<t4<<endl<<t5;
}
收获
这次训练赛很lqb,除了题意不明,数据没有,输出格式十分奇怪外,没有什么其他问题。
以上是关于2021.10.29--《21-22-1蓝桥训练4》的主要内容,如果未能解决你的问题,请参考以下文章