2017年蓝桥杯软件B组省赛试题

版权声明:本文章未经博主允许不得转载 https://blog.csdn.net/qq_42217376/article/details/88369681


购物单(简单计算)

using namespace std;
 
const int Max_n=100005;
typedef long long LL;
int vis[Max_n];

int main(){ 
    double x=
      180.90*      0.88+
      10.25*       0.65+
      56.14*        0.9+
     104.65*        0.9+
     100.30*       0.88+
     297.15*       0.5+
      26.75*       0.65+
     130.62*        0.5+
     240.28*       0.58+
     270.62*        0.8+
     115.87*       0.88+
     247.34*       0.95+
      73.21*        0.9+
     101.00*        0.5+
      79.54*        0.5+
     278.44*        0.7+
     199.26*        0.5+
      12.97*        0.9+
     166.30*       0.78+
     125.50*       0.58+
      84.98*        0.9+
     113.35*       0.68+
     166.57*        0.5+
      42.56*        0.9+
      81.90*       0.95+
     131.78*        0.8+
     255.89*       0.78+
     109.17*        0.9+
     146.69*       0.68+
     139.33*       0.65+
     141.16*       0.78+
     154.74*        0.8+
      59.42*        0.8+
      85.44*       0.68+
     293.70*       0.88+
     261.79*       0.65+
      11.30*       0.88+
     268.27*       0.58+
     128.29*       0.88+
     251.03*        0.8+
     208.39*       0.75+
     128.88*       0.75+
      62.06*        0.9+
     225.87*       0.75+
      12.89*       0.75+
      34.28*       0.75+
      62.16*       0.58+
     129.12*        0.5+
     218.37*        0.5+
     289.69*        0.8;
     printf("%f\n",x);//5200
    return 0;
}

等差素数列(素数筛,暴力枚举)

首先我们先筛选出所有的素数,然后我们枚举天数,如果符合条 件我们就输出天数.

//标记优化
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
 
const int Max_n=100005;
typedef long long LL;
int prime[Max_n],is_prime[Max_n];

int num;
void get_prime(){
	for(int i=2;i<=Max_n;i++) is_prime[i]=true;
	for(int i=2;i<=sqrt(Max_n);i++){
		if(is_prime[i]){
			for(int j=i*i;j<=Max_n;j+=i)
				is_prime[j]=false;
		}
	}
	num=1;
	for(int i=1;i<=Max_n;i++){
		if(is_prime[i])
			prime[num++]=i;
	}
}
int main(){ 
    get_prime();
    for(int i=1;i<=Max_n;i++){
    	int b=0;
    	for(int j=1;j<num;j++){
    		if(prime[j]+9*i>Max_n) break;
    		if(is_prime[prime[j]]){
    			if(is_prime[prime[j]+i]){
    				if(is_prime[prime[j]+2*i]){
    					if(is_prime[prime[j]+3*i]){
    						if(is_prime[prime[j]+4*i]){
    							if(is_prime[prime[j]+5*i]){
    								if(is_prime[prime[j]+6*i]){
    									if(is_prime[prime[j]+7*i]){
    										if(is_prime[prime[j]+8*i]){
    											if(is_prime[prime[j]+9*i]){
    												printf("%d\n",i);//210
    												b=1;
    											}
    										}
    									}
    								}
    							} 
    						}
    					}
    				}
    			}
    		}
    	}
    	if(b) break;
    }
    return 0;
}

承压计算(简单计算)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;

typedef long long LL;
const int Max_n=30;
double a[Max_n][Max_n];

int main() {
    int n=29;
    memset(a,0,sizeof(a));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++)
            scanf("%lf",&a[i][j]);
    }
    for(int i=2;i<=n+1;i++){
        for(int j=1;j<=i;j++){
            a[i][j]+=a[i-1][j]/2+a[i-1][j-1]/2;
        }
    }
    //for(int i=1;i<=n+1;i++){
    //	for(int j=1;j<=i;j++)
    //		printf("%lf  ",a[i][j]);
    //	printf("\n");
    //}
    double mmax=-1,mmin=1000000; 
    for(int i=1;i<=n+1;i++){
    	if(a[30][i]>mmax) mmax=a[30][i];
    	if(a[30][i]<mmin) mmin=a[30][i];
    }
    printf("%lf %lf\n",mmin,mmax);
    printf("%lf\n",2086458231/mmin*mmax);//72665192664
    return 0;
}
输入:
7 
5 8 
7 8 8 
9 2 7 2 
8 1 4 9 1 
8 1 8 8 4 1 
7 9 6 1 4 5 4 
5 6 5 5 6 9 5 6 
5 5 4 7 9 3 5 5 1 
7 5 7 9 7 4 7 3 3 1 
4 6 4 5 5 8 8 3 2 4 3 
1 1 3 3 1 6 6 5 5 4 4 2 
9 9 9 2 1 9 1 9 2 9 5 7 9 
4 3 3 7 7 9 3 6 1 3 8 8 3 7 
3 6 8 1 5 3 9 5 8 3 8 1 8 3 3 
8 3 2 3 3 5 5 8 5 4 2 8 6 7 6 9 
8 1 8 1 8 4 6 2 2 1 7 9 4 2 3 3 4 
2 8 4 2 2 9 9 2 8 3 4 9 6 3 9 4 6 9 
7 9 7 4 9 7 6 6 2 8 9 4 1 8 1 7 2 1 6 
9 2 8 6 4 2 7 9 5 4 1 2 5 1 7 3 9 8 3 3 
5 2 1 6 7 9 3 2 8 9 5 5 6 6 6 2 1 8 7 9 9 
6 7 1 8 8 7 5 3 6 5 4 7 3 4 6 7 8 1 3 2 7 4 
2 2 6 3 5 3 4 9 2 4 5 7 6 6 3 2 7 2 4 8 5 5 4 
7 4 4 5 8 3 3 8 1 8 6 3 2 1 6 2 6 4 6 3 8 2 9 6 
1 2 4 1 3 3 5 3 4 9 6 3 8 6 5 9 1 5 3 2 6 8 8 5 3 
2 2 7 9 3 3 2 8 6 9 8 4 4 9 5 8 2 6 3 4 8 4 9 3 8 8 
7 7 7 9 7 5 2 7 9 2 5 1 9 2 6 5 3 9 3 5 7 3 5 4 2 8 9 
7 7 6 6 8 7 5 5 8 2 4 7 7 4 7 2 6 9 2 1 8 2 9 8 5 7 3 6 
5 9 4 5 5 7 5 5 6 3 5 3 9 5 8 9 5 4 1 2 6 1 4 3 5 3 2 4 1 

方格分割(搜索)


在这里插入图片描述 在这里插入图片描述 在这里插入图片描述
我们把对称图形想象成我们要切去一部分图形,那么切割线就是一样的,我们从图的中心点开始搜索,然后判断能否到达边界,如果可以情况就+1.

#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
 
const int Max_n=105;
typedef long long LL;
int net[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int cnt=0,vis[Max_n][Max_n];

void dfs(int x,int y){
	if(x==0||y==0||x==6||y==6){
		cnt++;
		return ;
	}
	for(int i=0;i<4;i++){
		int tx=x+net[i][0];
		int ty=y+net[i][1];
		if(vis[tx][ty]) continue;
		vis[tx][ty]=1;
		vis[6-tx][6-ty]=1;
		dfs(tx,ty);
		vis[tx][ty]=0;
		vis[6-tx][6-ty]=0;
	}
	return ;
}

int main(){ 
	vis[3][3]=1;
	dfs(3,3);
	//有四种旋转方法,只保留一种即可 
	printf("%d\n",cnt/4);//509
    return 0;
}

取数位(简单计算)

答案:f(x/10,k)


最大公共子串(最长公共子序列)

答案:a[i-1][j-1]+1


日期问题(STL专题之sort排序)



1.找到所有可能的日期信息
2.判断当前日期是否合理,合理的存入数组
3.判断日期是否合理是需要从年月日分别考虑
4.记得排序~~~~~

#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int Max_n=10;
typedef long long LL;
int num=0;
int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

/*
 1.找到所有可能的日期信息
 2.判断当前日期是否合理,合理的存入数组
 3.判断日期是否合理是需要从年月日分别考虑 
 4.记得排序~~~~~ 
*/ 
 
struct Data{
	int year;
	int month;
	int day;
}data[Max_n]; 

bool operator <(const Data &a,const Data &b){
	if(a.year==b.year){
		if(a.month==b.month)
			return a.day<b.day;
		return a.month<b.month;
	}
	return a.year<b.year;
} 
//只有三种情况 (a,b,c)(c,a,b)(c,b,a)
bool judge(Data d){//判断当前日期是否合理
	 if(d.year<1960||d.year>2059)//年(1960,2059) 
	 	return false;
	if(d.month<=0||d.month>12)//月(1,12) 
		return false;
	if(d.year%400==0||(d.year%100!=0&&d.year%4==0)){//日 
		if(d.month==2) 
			return d.day>=1&&d.day<=29;
		return d.day>=1&&d.day<=a[d.month];
	}
	return d.day>=1&&d.day<=a[d.month];	 
}

void judge1(int a,int b,int c){//找到合理的日期,并且存入数组 
	Data d;
	d.year=a,d.month=b,d.day=c;
	if(judge(d))
		data[num++]=d;
} 
int main(){
	int a,b,c;
	scanf("%d/%d/%d",&a,&b,&c);
	judge1(1900+a,b,c);
	judge1(2000+a,b,c);
	
	judge1(1900+c,a,b);
	judge1(2000+c,a,b);
	
	judge1(1900+c,b,a);
	judge1(2000+c,b,a);
	
	sort(data,data+num);
	for(int i=0;i<num;i++){
		if(data[i].year==data[i+1].year&&data[i].month==data[i+1].month&&data[i].day==data[i+1].day)
			continue;
		printf("%d-%02d-%02d\n",data[i].year,data[i].month,data[i].day);
	}
	return 0;
}


包子凑数(欧几里得,思维)

首先我们要知道,这一组数如果 没有一组两两互质的数的话,他 们的最小公约数最小是2,此时 一定能把2的倍数都删去,其他的就没有办法了.如果有那么一组数是两两互质的就有有限 个数.

#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int Max_n=100005;
typedef long long LL;
int a[Max_n],vis[Max_n];

/*
 
*/ 
int gcd(int a,int b){
	if(a<b){int t=a;a=b;b=t;}
	return b==0?a:gcd(b,a%b);
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	int m=a[1];
	for(int i=2;i<=n;i++)
		m=gcd(m,a[i]);
	vis[0]=1;
	int sum=0;
	if(m==1){
		for(int i=1;i<=n;i++){
			for(int j=a[i];j<=Max_n;j++){
				if(vis[j-a[i]]) 
					vis[j]=1;//能够凑到的包子数	
			}
		}
		for(int i=1;i<=Max_n;i++)
			if(!vis[i])
				sum++;
		printf("%d\n",sum);
	}else{
		printf("INF\n");
	} 
	return 0;
}

分巧克力(二分)

#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
 
const int Max_n=100005;
typedef long long LL; 
int h[Max_n],w[Max_n];
int n,k;

/*二分天数即可*/ 
bool check(int mid){
	LL cnt=0;//注意数据类型,以及位置 
	for(int i=1;i<=n;i++)
		cnt+=(h[i]/mid)*(w[i]/mid);
	if(cnt<k)//切不出k块 
		return false;
	return true;
}

int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&h[i],&w[i]);
	int l=1,r=100000,ans=0;
	while(l<=r){
		int mid=l+(r-l)/2;
		if(check(mid)){//能够切出k尝试更大的边长 
			l=mid+1;
			ans=mid; 
		}else{
			r=mid-1;
		}
	}
	printf("%d\n",ans);
	return 0;
}

k倍区间(前缀和,思维)



我们先求一个前缀和,我们知道一个区间的和就是
sum[r]-sum[l-1],
如果需要满足题意此时就有
(sum[r]-sum[l-1])%k=0
我们就可以得到
sum[r]%k=sum[l-1]%k
只要两个前缀和取余相等,此时这个区间就符合题意.
1 1 ans+=0 ans=0 //前面没有与1相等的
2 1 ans+=1 ans=1 //前面有一个与1相等的
3 0 ans+=0 ans=1
4 0 ans+=1 ans=2
5 1 ans+=2 ans=4
最后在加上从头开始能够整除k的区间的个数即可.

#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int Max_n=100005;
typedef long long LL;
int a[Max_n];
LL cnt[Max_n],sum[Max_n];
LL ans=0; 

int main(){
	int n,k;
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++){
		sum[i]=(sum[i-1]+a[i])%k;
		ans+=cnt[sum[i]];
		cnt[sum[i]]++;
	}
	printf("%lld\n",ans+cnt[0]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42217376/article/details/88369681
今日推荐