2019 蓝桥杯省赛 B组模拟赛(一) 部分题解(持续更新)

 F. 程序设计:找质数

 

数据范围

对于 30\%30% 的数据 1 \le t \le 10^31≤t≤103。

对于 60\%60% 的数据 1 \le t \le 10^51≤t≤105。

对于 100\%100% 的数据 1 \le t \le 10^6, 4 \le n \le 10^61≤t≤106,4≤n≤106,nn 为偶数。

 

由于本题的数据范围过大,需要对素数预处理,普通的素数打表会TLE

所以我使用素数筛选法打表:

素数筛选法  详细解释

void isPrime ()
{
	memset(prim,0,sizeof(prim));
	prim[0]=prim[1]=1;
	for(int i=2; i*i <= maxn; i++)
		if(prim[i]==0)
		{
			for(int j=i+i;j<=maxn;j+=i)
				prim[j]=1;
		}
}

 

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int prim[maxn];  //存储素数序列 


void isPrime ()  //将素数都标记为0 
{
	memset(prim,0,sizeof(prim));   //不初始化也可以 全局的数组已经被赋值为0 
	prim[0]=prim[1]=1;             // 0和1不是素数 
	for(int i=2; i*i <= maxn; i++)
		if(prim[i]==0)
		{
			for(int j=i+i;j<=maxn;j+=i)
				prim[j]=1;
		}
}
//用cin过不了
int main()
{
	isPrime();
	int n,num;
	scanf("%d",&n);
	while(n--)
	{
		scanf("%d",&num);
		for(int i=2;;i++)
		{
			if(!prim[i]&&!prim[num-i])  //卡条件 
			{
				printf("%d %d\n",i,num-i);
				break;
			}
		}
	}
	return 0;	
} 

 


 G. 程序设计:后缀字符串

 

该题有点坑,第一次我用得是暴力模拟,就是简单的在双重for循环中判断是否存在字符串后缀

暴力模拟:(过了50%的测试点)

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
string str[maxn];

int main()
{
	std::ios::sync_with_stdio(false);
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>str[i];
	
	for(int i=0;i<n;i++)
	{
		int ans=0;//每次都初始化为0 
		for(int j=0;j<n;j++)
		{
			int pos=str[j].length()-str[i].length();
			int flag=1;
			if(pos<0)      //后一个字符长度小于前一个就一定不能包含前一个 
				continue;	
			for(int k=0;k<str[i].length();k++)//开始查询 
			{
				if(str[i][k]!=str[j][pos+k])//如果不是后缀 
				{
					flag=0; 
					break;	
				}	
			}
			if(flag)	ans++;	
		}
		cout<<ans<<endl;	
	}	
	return 0;
} 

 

2.使用map容器,由于map容器由键(key)和值(value)构成一对单元,key 和 value可以是任意你需要的类型。

这种关联类容器可以使得操作的时间复杂度大大降低

官方题解使用了substr:

substr的2种用法:
假设:string s = "0123456789";

string s1 = s.substr(7); //表示从下标为7开始一直到结尾:s1 = "789"

string s2 = s.substr(7, 2); //从下标为5开始截取长度为2位:s2 = "78"

 

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
string a[N];
int main() {
    map<string, int> mp;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
	{
        cin >> a[i];
        for (int j = 0; j < a[i].size(); j++) 
		{
            mp[a[i].substr(j)]++;    
        }
    }
    for (int i = 0; i < n; i++) 
	{
        cout << mp[a[i]] << endl;
    }
    return 0;
}


 


H. 程序设计:轻重搭配

 

采用贪心策略,要注意先对体重进行升序排序,然后再将第1轻的人与第n/2轻的人进行配对,如果满足条件则配对成功,所需门票数减一,且pos后移。若不满足条件则pos后移,将第1轻的人与第n/2 +1 轻的人进行配对,依次类推

 

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+5;


int main()
{
    std::ios::sync_with_stdio(false);
	int n;
    int a[maxn];
    cin>>n;
    for(int i=0;i<n;i++)
       cin>>a[i];
    sort(a,a+n);    //按体重排序 
    int pos=n/2,couple=n;  //pos是搜索的起点,couple是所需的门票数 
    for(int i=0;i<n/2;i++)
    {
       while(a[i]*2>a[pos] && pos<n) //如果不满足条件,pos后移 
           	pos++;
       if(pos==n)   //搜索完毕,及时退出 
           	break;
	   if(a[i]*2<=a[pos])   //满足条件 
       {
           couple--;  //门票数减一 
           pos++;    //注意pos的后移,搜索下一配对 
       }  
    }
	cout<<couple<<endl;
	return 0;
}

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值