2017年藍橋杯軟件B組省賽試題




購物單(簡單計算)

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;
}


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com