第十二届蓝桥杯省赛第二场C++B组真题
Posted 脆皮小刺猬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十二届蓝桥杯省赛第二场C++B组真题相关的知识,希望对你有一定的参考价值。
目录
特殊年份
今年是 20212021 年,20212021 这个数字非常特殊,它的千位和十位相等,个位比百位大 11,我们称满足这样条件的年份为特殊年份。
输入 55 个年份,请计算这里面有多少个特殊年份。
输入格式
输入 55 行,每行一个 44 位十进制数(数值范围为 10001000 至 99999999),表示一个年份。
输出格式
输出一个整数,表示输入的 55 个年份中有多少个特殊年份。
输入样例:
2019
2021
1920
2120
9899
输出样例:
2
样例解释
20212021 和 98999899 是特殊年份,其它不是特殊年份。
#include<iostream>
using namespace std;
bool check(int n)
int g=n%10;
int s=n%100/10;
int b=n/100%10;
int q=n/1000;
//cout<<n<<' '<<q<<b<<s<<g<<endl;
if(q==s&&(g-b==1))return true;
return false;
int main()
int ans=0;int n;
while(cin>>n)
if(check(n))ans++;
cout<<ans<<endl;
return 0;
小平方
小蓝发现,对于一个正整数 nn 和一个小于 nn 的正整数 vv,将 vv 平方后对 nn 取余可能小于 nn 的一半,也可能大于等于 nn 的一半。
请问,在 11 到 n−1n−1 中,有多少个数平方后除以 nn 的余数小于 nn 的一半。
例如,当 n=4n=4 时,1,2,31,2,3 的平方除以 44 的余数都小于 44 的一半。
又如,当 n=5n=5 时,1,41,4 的平方除以 55 的余数都是 11,小于 55 的一半。
而 2,32,3 的平方除以 55 的余数都是 44,大于等于 55 的一半。
输入格式
输入一行包含一个整数 nn。
输出格式
输出一个整数,表示满足条件的数的数量。
数据范围
1≤n≤100001≤n≤10000
输入样例:
5
输出样例:
2
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
int main()
cin>>n;
int ans=0;
for(int i=1;i<n;i++)
if(i*i%n*2<n)ans++;
cout<<ans<<endl;
return 0;
完全平方数
一个整数 aa 是一个完全平方数,是指它是某一个整数的平方,即存在一个整数 bb,使得 a=b2a=b2。
给定一个正整数 nn,请找到最小的正整数 xx,使得它们的乘积是一个完全平方数。
输入格式
输入一行包含一个正整数 nn。
输出格式
输出找到的最小的正整数 xx。
数据范围
对于 30%30% 的评测用例,1≤n≤10001≤n≤1000,答案不超过 10001000。
对于 60%60% 的评测用例,1≤n≤1081≤n≤108,答案不超过 108108。
对于所有评测用例,1≤n≤10121≤n≤1012,答案不超过 10121012。
输入样例1:
12
输出样例1:
3
输入样例2:
15
输出样例2:
15
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
typedef long long ll;
using namespace std;
ll n;
int main()
cin>>n;
ll ans=1;
for(ll i=2;i<=n/i;i++)
if(n%i==0)
int s=0;
while(n%i==0)s++,n/=i;
if(s%2)ans*=i;
if(n>1)ans*=n;
cout<<ans<<endl;
return 0;
负载均衡
有 nn 台计算机,第 ii 台计算机的运算能力为 vivi。
有一系列的任务被指派到各个计算机上,第 ii 个任务在 aiai 时刻分配,指定计算机编号为 bibi,耗时为 cici 且算力消耗为 didi。
如果此任务成功分配,将立刻开始运行,期间持续占用 bibi 号计算机 didi 的算力,持续 cici 秒。
对于每次任务分配,如果计算机剩余的运算能力不足则输出 −1−1,并取消这次分配,否则输出分配完这个任务后这台计算机的剩余运算能力。
输入格式
输入的第一行包含两个整数 n,mn,m,分别表示计算机数目和要分配的任务数。
第二行包含 nn 个整数 v1,v2,⋅⋅⋅vnv1,v2,···vn,分别表示每个计算机的运算能力。
接下来 mm 行每行 44 个整数 ai,bi,ci,diai,bi,ci,di,意义如上所述。数据保证 aiai 严格递增,即 ai<ai+1ai<ai+1。
输出格式
输出 mm 行,每行包含一个数,对应每次任务分配的结果。
数据范围
对于 20%20% 的评测用例,n,m≤200n,m≤200。
对于 40%40% 的评测用例,n,m≤2000n,m≤2000。
对于所有评测用例,1≤n,m≤200000,1≤ai,ci,di,vi≤109,1≤bi≤n1≤n,m≤200000,1≤ai,ci,di,vi≤109,1≤bi≤n。
输入样例:
2 6
5 5
1 1 5 3
2 2 2 6
3 1 2 3
4 1 6 1
5 1 3 3
6 1 3 4
输出样例:
2
-1
-1
1
-1
0
样例解释
时刻 11,第 11 个任务被分配到第 11 台计算机,耗时为 55,这个任务时刻 66 会结束,占用计算机 11 的算力 33。
时刻 22,第 22 个任务需要的算力不足,所以分配失败了。
时刻 33,第 11 个计算机仍然正在计算第 11 个任务,剩余算力不足 33,所以失败。
时刻 44,第 11 个计算机仍然正在计算第 11 个任务,但剩余算力足够,分配后剩余算力 11。
时刻 55,第 11 个计算机仍然正在计算第 1,41,4 个任务,剩余算力不足 44,失败。
时刻 66,第 11 个计算机仍然正在计算第 44 个任务,剩余算力足够,且恰好用完。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 200010;
priority_queue<PII,vector<PII>,greater<PII>>q[N];
int s[N];
int main()
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>s[i];
while(m--)
int a,b,c,d;
cin>>a>>b>>c>>d;
while(q[b].size()&&q[b].top().x<=a)
s[b]+=q[b].top().y;
q[b].pop();
if(s[b]<d)cout<<-1<<endl;
else
q[b].push(a+c,d);
s[b]-=d;
cout<<s[b]<<endl;
return 0;
国际象棋
众所周知,“八皇后” 问题是求解在国际象棋棋盘上摆放 88 个皇后,使得两两之间互不攻击的方案数。
已经学习了很多算法的小蓝觉得 “八皇后” 问题太简单了,意犹未尽。作为一个国际象棋迷,他想研究在 N×MN×M 的棋盘上,摆放 KK 个马,使得两两之间互不攻击有多少种摆放方案。
由于方案数可能很大,只需计算答案除以 10000000071000000007 (即 109+7109+7) 的余数。
如下图所示,国际象棋中的马摆放在棋盘的方格内,走 “日” 字,位于 (x,y)(x,y) 格的马(第 xx 行第 yy 列)可以攻击 (x+1,y+2)(x+1,y+2)、(x+1,y−2)(x+1,y−2)、(x−1,y+2)(x−1,y+2)、(x−1,y−2)(x−1,y−2)、(x+2,y+1)(x+2,y+1)、(x+2,y−1)(x+2,y−1)、(x−2,y+1)(x−2,y+1) 和 (x−2,y−1)(x−2,y−1) 共 88 个格子。
输入格式
输入一行包含三个正整数 N,M,KN,M,K,分别表示棋盘的行数、列数和马的个数。
输出格式
输出一个整数,表示摆放的方案数除以 10000000071000000007 (即 109+7109+7) 的余数。
数据范围
对于 5%5% 的评测用例,K=1K=1;
对于另外 10%10% 的评测用例,K=2K=2;
对于另外 10%10% 的评测用例,N=1N=1;
对于另外 20%20% 的评测用例,N,M≤6,K≤5N,M≤6,K≤5;
对于另外 25%25% 的评测用例,N≤3,M≤20,K≤12N≤3,M≤20,K≤12;
对于所有评测用例,1≤N≤6,1≤M≤100,1≤K≤201≤N≤6,1≤M≤100,1≤K≤20。
输入样例1:
1 2 1
输出样例1:
2
输入样例2:
4 4 3
输出样例2:
276
输入样例3:
3 20 12
输出样例3:
914051446
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 105,M=1<<6,K=21,Mod=1e9+7;
int n,m,k;
int f[N][M][M][K];
int get_count(int x)
int ans=0;
while(x)
ans++;
x-=x&-x;
return ans;
int main()
cin>>n>>m>>k;
f[0][0][0][0]=1;
for(int i=1;i<=m;i++)
for(int a=0;a<1<<n;a++)
for(int b=0;b<1<<n;b++)
if(a&(b<<2)||b&(a<<2))continue;
for(int c=0;c<1<<n;c++)
if(c&(b<<2)||b&(c<<2))continue;
if(c&(a<<1)||a&(c<<1))continue;
int t=get_count(c);
for(int u=t;u<=k;u++)
f[i][b][c][u]=(f[i][b][c][u]+f[i-1][a][b][u-t])%Mod;
int res=0;
for(int i=0;i<1<<n;i++)
for(int j=0;j<1<<n;j++)
res=(res+f[m][i][j][k])%Mod;
cout << res << endl;
return 0;
第十二届蓝桥杯大赛软件赛省赛第二场C++B组
自己参加的是第一次场的,打的很烂。做了一下第二场的题,我是真想骂街。
第二场普遍简单许多。
目录
A: 求余 【签到】
答案: 1
#include<cstdio>
#include<iostream>
using namespace std;
int main(void)
{
cout<<2021%20<<endl;
return 0;
}
B: 双阶乘 【签到】
答案: 59375
#include<cstdio>
#include<iostream>
using namespace std;
int main(void)
{
long long int ans=1;
for(int i=2021;i>=1;i=i-2)
{
ans*=i;
ans=ans%100000;
}
cout<<ans<<endl;
return 0;
}
C: 格点 【签到题】
答案: 15698
#include<cstdio>
#include<iostream>
using namespace std;
int main(void)
{
int ans=0;
for(int i=1;i<=2021;i++)
{
for(int j=1;j<=2021;j++)
{
if(i*j<=2021) ans++;
}
}
cout<<ans<<endl;
return 0;
}
D: 整数分解 【DP】
答案: 691677274345
f[i][j] 表示将数字j分成i份有多少种方法
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
long long int f[6][2025];
int main(void)
{
for(int i=1;i<=2021;i++) f[1][i]=1;
for(int i=2;i<=5;i++)
{
for(int j=1;j<=2021;j++)
{
for(int k=1;k<=2021;k++)
{
if(j-k>=1) f[i][j]+=f[i-1][j-k];
}
}
}
cout<<f[5][2021];
return 0;
}
E: 城邦 【最小生成树板子题】
答案: 4046
自己求一下每一条边的权,用最小生成树模板就OK了。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2022;
const int INF=0x3f3f3f3f;
int g[N][N],dist[N];
bool st[N];
int n,m;
int prim()
{
memset(dist,0x3f,sizeof dist);
int res=0;
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=1;j<=n;j++)
if(!st[j]&&(t==-1 || dist[t] > dist[j] )) t=j;
st[t]=true;
if(i) res+=dist[t];
if(i&&dist[t]==INF) return INF;
for(int j=1;j<=n;j++) dist[j]=min(dist[j],g[t][j]);
}
return res;
}
int main(void)
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j) g[i][j]=0;
else g[i][j]=INF;
}
}
for(int i=1;i<=2021;i++)
{
for(int j=1;j<=2021;j++)
{
if(i!=j)
{
int a=i,b=j;
int sum=0;
while(a||b)
{
if(a%10!=b%10) sum+=a%10+b%10;
a/=10,b/=10;
}
g[i][j]=sum;
g[j][i]=sum;
}
}
}
int t=prim();
cout<<t<<endl;
return 0;
}
F: 特殊年份 【签到题】
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int ans;
bool check(int x)
{
int a=x/1000;
int b=(x/100)%10;
int c=(x/10)%10;
int d=x%10;
if(a==c&&(d-b==1)) return true;
else return false;
}
int main(void)
{
int x;
for(int i=0;i<5;i++){
cin>>x;
if(check(x)) ans++;
}
cout<<ans<<endl;
return 0;
}
G: 小平方 【签到题】
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main(void)
{
int n; cin>>n;
double a=n/2.0;
int ans=0;
for(int i=1;i<=n-1;i++)
{
int temp=i*i;
if((temp%n)<a) ans++;
}
cout<<ans<<endl;
return 0;
}
H: 完全平方数 【质因子分解】
解析: 你要知道,要想可以开平方,其质因子必须成对出现。不是偶数的补一下就好了。
例如: 12=2x2x3 , 3的个数是一个,不是偶数所以得补一个3 结果 12x3=36 就可以开平方了。
注意: 本题数据范围大要用 long long 可能会有一个很大的质数的情况。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
map<long long int,long long int> mp;
int main(void)
{
long long int x; cin>>x;
for(int i=2;i<=x/i;i++)
{
while(x%i==0) mp[i]++,x/=i;
}
if(x!=1) mp[x]++;
long long int ans=1;
for(map<long long int,long long int>::iterator it=mp.begin();it!=mp.end();it++)
{
long long int temp=it->second;
if(temp&1) ans*=it->first;
}
cout<<ans<<endl;
return 0;
}
I: 负载均衡 【优先队列 / 模拟】
用优先队列来维护当前时间哪一个机器的任务完成了,释放资源。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1e5*2+10;
struct machine
{
int id;//机器
int sum;//算力
int end;//结束的时间
friend bool operator < (machine f1,machine f2)//时间从小到大
{
return f1.end > f2.end;
}
}stu;
int sum[N];//每台计算机的当前可用的算力
int n,m;
int main(void)
{
cin>>n>>m;
priority_queue<machine> heap;
for(int i=1;i<=n;i++) scanf("%d",&sum[i]);
while(m--)
{
bool flag=false;
int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d);
while(heap.size())//判断可不可以释放算力
{
auto t=heap.top();
if(t.end<=a)
{
heap.pop();
sum[t.id]+=t.sum;
}
else break;
}
if(sum[b]>=d)//可以计算
{
stu.id=b,stu.sum=d,stu.end=a+c;
heap.push(stu);
sum[b]-=d;
cout<<sum[b]<<endl;
flag=true;
}
if(!flag) cout<<-1<<endl;
}
}
J: 国际象棋 【状压DP / 水平有限不会写】
以上是关于第十二届蓝桥杯省赛第二场C++B组真题的主要内容,如果未能解决你的问题,请参考以下文章
第十二届蓝桥杯省赛第二场C++A/B组 AcWing 3492. 负载均衡树状数组/堆