蓝桥杯模拟赛 4

P8780 [蓝桥杯 2022 省 B] 刷题统计

P8800 [蓝桥杯 2022 国 B] 卡牌

P8778 [蓝桥杯 2022 省 A] 数的拆分

P8808 [蓝桥杯 2022 国 C] 斐波那契数组

P8786 [蓝桥杯 2022 省 B] 李白打酒加强版

P8781 [蓝桥杯 2022 省 B] 修建灌木

P8772 [蓝桥杯 2022 省 A] 求和

P8799 [蓝桥杯 2022 国 B] 齿轮

A-刷题统计

算出一周能写多少题,然后求一下余数

#include <bits/stdc++.h>
using namespace std;

#define int long long 

int32_t main(){
	int a , b , n;
	cin >> a >> b >> n;
	int t = 5 * a + 2 * b;
	int res = n / t;
	n %= t;
	res *= 7;
	for( int i = 1 ; i <= 5 ; i ++ )
		if( n > 0 ) n -= a , res ++;
	for( int i = 1 ; i <= 2 ; i ++ )
		if( n > 0 ) n -= b , res ++;
	cout << res;
	return 0;
}

B-齿轮

物理知识,所有齿轮的线速度相同,所以角速度就是就是第一个齿轮和最后一个齿轮的半径比

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5+5;
bitset<N> vis;

int read(){
	int x = 0 , ch = getchar();
	while( ch < '0' || ch > '9' ) ch = getchar();
	while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1) + ch-'0' , ch = getchar();
	return x;
}
int32_t main(){
	int n = read() , q = read();
	vector<int> a(n);
	for( auto &i : a ) i = read() , vis[i] = 1;
	sort(a.begin(), a.end());
	for( int x , f ; q ; q -- ){
		x = read() , f = 0;
		for( auto i : a ){
			if( x * i >= N ) break;
			if( vis[x*i] ) { f = 1 ; break; }
		}
		if( f ) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}

C-求和

先提公因式,然后发现算一下后缀和就好

#include <bits/stdc++.h>
using namespace std;

#define int long long 


int32_t main(){
	int n;
	cin >> n;
	vector<int> a(n);
	for( auto & i : a ) cin >> i;
	auto b = a;
	for( int i = n-2 ; i > 0 ; i -- ) b[i] += b[i+1];
	int res = 0;
	for( int i = 0 ; i < n-1 ; i ++ )
		res += a[i] * b[i+1];
	cout << res;

	return 0;
}

D-修建灌木

打表找规律,第一个数是2n-2,然后每次递减2直到中间,后半部分与前半部分对称

#include <bits/stdc++.h>
using namespace std;


int32_t main(){
	int n; cin >> n;
	for( int i = 1 ; i <= n ; i ++ )
		printf("%d\n" , 2*max( n-i , i-1 )) ;
	return 0;
}

E-李白打酒加强版

动态规划f[i][j][k]表示遇到i次店j次花有k斗酒的方案数,答案就是f[n][m-1][1],并且k的区域值范围是[1,m],然后更具题目描述转移方程即可,注意如果上一次遇到了店,当前的k一定是偶数。

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int mod = 1e9+7;
int f[105][105][105] , n , m;

int32_t main(){
	cin >> n >> m;
	f[0][0][2] = 1;
	for( int i = 0 ; i <= n ; i ++ )
		for( int j = 0 ; j < m ; j ++ )
			for( int k = 0 ; k <= m ; k ++ ){
				if( j > 0 ) f[i][j][k] = ( f[i][j][k] + f[i][j-1][k+1] ) % mod;
				if( i > 0 && k % 2 == 0 ) f [i][j][k] = ( f[i][j][k] + f[i-1][j][k/2] ) % mod; 
			}
				
	cout << f[n][m-1][1];
	return 0;
}

F-斐波那契数组

这里的斐波那契数组与正常的斐波那契相比是每一位都成了一个倍数,所以求出原序列用到的哪个倍数最多就是答案。

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5+5;
bitset<N> vis;

int read(){
	int x = 0 , ch = getchar();
	while( ch < '0' || ch > '9' ) ch = getchar();
	while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1) + ch-'0' , ch = getchar();
	return x;
}
int32_t main(){
	int n = read();
	vector<int> a(n);
	a[0] = a[1] = 1;
	for( int i = 2 ; i < n ; i ++ ) a[i] = a[i-1] + a[i-2];
	map<int,int> st;
	for( int i = 0 , x ; i < n ; i ++ ){
		x = read();
		if( x % a[i] == 0 ) st[ x / a[i] ] ++;
	}
	int res = 0;
	for( auto [ k , v ] : st )
		res = max( res , v );
	cout << n - res << "\n";
	return 0;
}

G-数的拆分

因为2和3可以组合出大于1的所有数字,所以最终一定是表示为\(x_1^2\cdot x_2^3\)的形式,所以我们把原数质因数分解后判断有没有质因子的次方数是1即可。我们需要小于\(\log_5(10^{18})\)的质数即可完成质因数分解,这个数不到4000。然后如果质因数分解后剩余有余数,我们要判断这个数本身是不是完全平方数或完全立方数。

#include <bits/stdc++.h>
using namespace std;

#define int long long

int read(){
	int x = 0 , ch = getchar();
	while( ch < '0' || ch > '9' ) ch = getchar();
	while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1) + ch-'0' , ch = getchar();
	return x;
}

vector<int> prime;

bool check( int x ){
	int l = 1 , r = 1e9+5 , mid , ans = 1;
	while( l <= r ){
		mid = ( l + r ) >> 1;
		if( mid * mid <= x ) ans = mid , l = mid + 1;
		else r = mid - 1;
	}
	if( ans * ans == x ) return true;
	l = 1 , r = 1e6+5 , ans = 1;
	while( l <= r ){
		mid = ( l + r ) >> 1;
		if( mid * mid * mid <= x ) ans = mid , l = mid + 1;
		else r = mid - 1;
	}
	if( ans * ans * ans == x ) return true;
	return false;
}

void solve(){
	int x = read();
	if( check(x) ){
		printf("yes\n");
		return;
	}
	for( auto i : prime ){
		if( x % i ) continue;
		int cnt = 0;
		while( x % i == 0 ) x /= i , cnt ++;
		if( cnt == 1 ) {
			printf("no\n");
			return ;
		}
	}
	if( check(x) ) printf("yes\n");
	else printf("no\n");
	return;
}

void init(){
	const int N = 4000;
	bitset<N> vis;
	for( int i = 2 ; i < N ; i ++ ){
		if( vis[i] == 0 ) prime.push_back(i);
		for( auto j : prime ){
			if( i * j >= N ) break;
			vis[i*j] = 1;
		}
	}
	return;
}

int32_t main(){
	init();
	for( int t = read(); t ; t -- )
		solve();
	return 0;
}

H-卡牌

二分答案,\(O(n)\)判断即可

#include <bits/stdc++.h>
using namespace std;

#define int long long

int read(){
	int x = 0 , ch = getchar();
	while( ch < '0' || ch > '9' ) ch = getchar();
	while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1) + ch-'0' , ch = getchar();
	return x;
}
int32_t main(){
	int n = read() , m = read();
	vector<int> a(n) , b(n);
	for( auto & i : a ) i = read();
	for( auto & i : b ) i = read();
	
	auto check = [=]( int x ){
		int cnt = 0;
		for( int i = 0 ; i < n ; i ++ )
			if( a[i] + b[i] < x ) return false;
			else cnt += max( 0ll , x-a[i] );
		return cnt <= m;
	};

	int l = 1 , r = 1e6+5 , ans = 0 , mid;
	while( l <= r ){
		mid = ( l + r ) >> 1;
		if( check(mid) ) ans = mid , l = mid + 1;
		else r = mid - 1;
	}
	cout << ans << "\n";
	return 0;
}
posted @ 2023-02-14 00:04  PHarr  阅读(43)  评论(0编辑  收藏  举报