2022蓝桥杯初赛C/C++B组题解

A:九进制转十进制
#include<iostreamod>  //1 
#include<cmath>
using namespace std;
int main()
{
int n=2022;
int count=0,num=0;
while(n)
{
num+=(n%10)*pow(9,count);
n/=10;
count++;
}
printf("%d\n",num);
return 0;
}
B:顺子日期
#include<iostream>      //2
using namespace std;
int main()
{
cout<<14<<endl;
return 0;
}
C:刷题统计
#include<iostream>     /3
using namespace std;
//sum为一周做题数,x为做了多少周,m为周几做 
int main()
{
long long int a,b,n,x,m,num=0;
cin>>a>>b>>n;
long long int sum=5*a+2*b;
x=n/sum;
n-=sum*x;
m=n/a;
if(m>=5)
{
n-=5*a;
if(n>b)
num=7;
else
num=6;
} 
else
{
if(n%a==0)
num=m;
else
num=m+1;
}
num+=7*x;
cout<<num<<endl;
return 0;
} 
D:修建灌木
#include<iostream>    //4
#include<algorithm>
using namespace std;
const int N=1e4+10;
int a[N];
int main() 
{
int n;
cin>>n;
for(int i=1;i<=n-i+1;i++)
{
a[i]=2*(n-i);
a[n-i+1]=a[i];
}
for(int i=1;i<=n;i++)
{
cout<<a[i]<<endl;
}
return 0;
}
E:X进制减法
#include<iostream>      //5
#include<algorithm>
#include<cmath> 
#include<cstring>
using namespace std;
const int N=1e6+10;
long long int a[N],b[N]={0},c[N];
int main()
{
long long int n,ma,mb;
cin>>n;
cin>>ma;
for(int i=ma;i>=1;i--)
{
cin>>a[i];
}
cin>>mb;
for(int i=mb;i>=1;i--)
{
cin>>b[i];
    }
    for(int i=ma;i>=1;i--)
{
c[i]=max(a[i],b[i])+1;
if(c[i]<2)
{
c[i]=2;
}
}
long long int x=1,cha=0;
    for(int i=1;i<=ma;i++)
    {
    cha+=((a[i]-b[i])*x)%1000000007;
    x*=c[i];
    x=x%1000000007;
    }
    cout<<cha%1000000007<<endl;
    return 0;
}
F:统计子矩阵
#include<iostream>
#include<algorithm>
using namespace std;
const int N=666;
long long int a[N][N],b[N][N];
int main()
{
long long int n,m,k,num=0;
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
b[i][j]=b[i-1][j]+a[i][j];
}
}
long long int l=1,sum=0;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
l=1;
sum=0;
for(int r=1;r<=m;r++)
{
long long int r1=b[j][r]-b[i-1][r];
if(sum+r1<=k)
{
sum+=r1;
num+=r-l+1;
} 
else
{
long long int l1=b[j][l]-b[i-1][l];
while(l!=r&&sum+r1>k)
{
sum-=l1;
l++;
l1=b[j][l]-b[i-1][l];
}
if(sum+r1<=k)
{
sum+=r1;
num+=r-l+1;
}
else
l++;
}
}
}
}
cout<<num<<endl;
return 0;
}
G:积木画

本题是一个dp问题,由于用二维dp比较麻烦,可以使用一维dp,将I型积木看成一个格子,L型积木为1.5个格子,所以L型积木必须要2个一组,由于I型积木有竖着摆和横着摆2种方式,所以要乘2;

所以递推公式为:x[i]=2*x[i-1]+x[i-3];

#include<iostream>
#include<algorithm>
using namespace std;
const int mod=1000000007;
const int N=1e7+10;
long long int x[N];
int main()
{
long long int n;
cin>>n;
x[1]=1;
x[2]=2;
x[3]=5;
for(int i=4;i<=n;i++)
{
x[i]=(2*x[i-1]%mod+x[i-3]%mod)%mod;
}
cout<<x[n]%mod<<endl;
return 0;
} 
H:扫雷
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N = 5e4 + 10, M = 1e6 + 7, X = 1e9 + 1;
int n, m;
struct node {int x, y, r;}b[N];
typedef long long ll;
ll Hash[M]; bool vis[N];
int id[M], res; 
ll get_hs(int x, int y) { return (ll)x * X + y; }
int find(int x, int y) {
ll hs = get_hs(x, y);
int key = (hs % M + M) % M; 
while (Hash[key] != -1 && Hash[key] != hs) {
key++;
if (key == M) key = 0; 
} return key;
}
bool check(int x1, int y1, int r, int x, int y) {
int d = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y);
return d <= r * r;
}
void bfs(int pos) {
queue<int> q;
q.push(pos);
vis[pos] = 1;
while (q.size()) {
int t = q.front();
q.pop();
int x = b[t].x, y = b[t].y, r = b[t].r;
for (int xx = x - r; xx <= x + r; xx++) { 
for (int yy = y - r; yy <= y + r; yy++) {
int key = find(xx, yy);
if (id[key] && !vis[id[key]] && check(x, y, r, xx, yy)) {
int pos = id[key];
vis[pos] = 1;
q.push(pos);
}
}
}
}
}
int main() {
cin >> n >> m;
memset(Hash, -1, sizeof(Hash));
int x, y, r;
for (int i = 1; i <= n; i++) { 
cin >> x >> y >> r;
b[i] = { x, y, r };
int key = find(x, y);
if (Hash[key] == -1) Hash[key] = get_hs(x, y); 
if (!id[key] || b[id[key]].r < r) id[key] = i;
}
for (int i = 1; i <= m; i++) { 
cin >> x >> y >> r;
for (int xx = x - r; xx <= x + r; xx++) 
for (int yy = y - r; yy <= y + r; yy++) {
int key = find(xx, yy);
if (id[key] && !vis[id[key]] && check(x, y, r, xx, yy)) bfs(id[key]);
}
}
for (int i = 1; i <= n; i++) {
int key = find(b[i].x, b[i].y); 
int pos = id[key];
if (pos && vis[pos]) res++; 
}
cout << res;
return 0;
}
I:李白打酒加强版

状态设计:dp[i][j][k]的值表示遇到i家店,j朵花,酒壶中还剩k斗酒的可能情况数;

状态转移方程:dp[i][j][k]=dp[i-1][j][k/2](i>1&&k%2==0) + dp[i][j-1][k+1](j>1);

边界设计:除了dp[0][0][2]=1,其他元素全为0;

他一共遇到店n次,遇到花m次。已知最后一次遇到的是花, 他正好把酒喝光了;所以

最后一次肯定遇到的是花,那么最后的结果便是dp[N][M-1][1];

#include<iostream>
#include<cstring>
using namespace std;
const int mod=1000000007,N=110;
long long dp[N * 2][N][N];    /* 店,花,酒 */
void slove()
{
    int n, m;
    cin>>n>>m;
    memset(dp, 0, sizeof dp);
    dp[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(i&&k%2==0)
                    dp[i][j][k]+=dp[i-1][j][k/2]; /* 遇到店 */
                if (j)
                    dp[i][j][k]+=dp[i][j-1][k+1]; /* 遇到花 */
                dp[i][j][k]%=mod;
            }
    cout<<dp[n][m-1][1]<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
{
slove();
}
return 0;
}
J:砍竹子

贪心,先将高的竹子砍了,可能这些竹子之后会和矮的竹子一起砍了。然后用a[i][j]记录第i棵树砍了j次后的高度,开始的砍树次数就是所有的树都一次一次地砍为 1 所需要的次数和,然后遍历如果发现有相邻的两棵树高度相同我们的砍树次数就可以减少1 。

#include<iostream>
#include<algorithm>
#include<cmath>
typedef long long int ll;
using namespace std;
const int N=2e5+10;
ll a[N][8],b[8];
int main()
{
ll num=0,n,x,t;
cin>>n;
for(int i=1;i<=n;i++)
{
t=0;
cin>>x;
while(x!=1)
{
b[++t]=x;
x=sqrt(x/2+1);
}
num+=t;
for(int j=1;t>0;j++,t--)
{
a[i][j]=b[t];
}
}
for(int i=1;i<=7;i++)
{
for(int j=2;j<=n;j++)
{
if(a[j][i]&&a[j][i]==a[j-1][i])
num--;
}
}
cout<<num<<endl;
return 0;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 蓝桥杯C初级省赛题目是一道程序设计题,要求参赛者设计程序,找出给定数中的最大值和最小值,并计算它们的差值。 对于这道题目,可以通过遍历数的方式找出最大值和最小值,并计算它们的差值。首先,设定两个变量max和min,分别代表最大值和最小值,初始值分别为数的第一个元素。然后,遍历数的每一个元素,如果该元素大于max,则将max更新为该元素,如果该元素小于min,则将min更新为该元素。最后,用max减去min,即可得到最大值和最小值的差值。 具体的算法步骤如下: 1. 设定变量max和min,初始值为数的第一个元素arr[0]。 2. 遍历数的每一个元素arr[i],从下标1开始。 3. 如果arr[i]大于max,则更新max为arr[i]。 4. 如果arr[i]小于min,则更新min为arr[i]。 5. 继续遍历数,直到最后一个元素arr[n-1]。 6. 计算差值diff,即max减去min。 7. 输出差值diff。 这样就可以得到数中最大值和最小值的差值。这道题目考察了参赛者对于数遍历和条件判断的理解和应用。编写代码时,可以使用for循环来遍历数,用if语句进行条件判断,并利用变量来存储最大值和最小值。最后,输出差值即可。这道题目考验的是参赛者的基本编程能力和对数处理的熟练程度。 ### 回答2: 蓝桥杯C初级省赛题目要求解决一个具体的编程问题,常见的包括数学问题、字符串处理、图形绘制等。以某年度的蓝桥杯C初级省赛题目为例,该题目为编写一个程序,输入两个整数a和b,输出它们的和。 首先,我们要编写一个C程序,可以使用C语言编译器来实现。通过获取用户输入的两个整数a和b,可以使用变量来存储这两个值。 接下来,我们可以通过将这两个整数相加,并将结果存储在一个新的变量中。 最后,我们可以使用printf函数来输出计算结果,以便用户可以看到这两个整数的和。 这个题目比较简单,只需要使用基本的C语言知识即可完成。例如,可以使用scanf函数来获取用户的输入,使用运算符+来进行两个变量的相加,使用printf函数来输出结果。 在编写代码的过程中,需要注意输入和输出的格式,以及边界条件的处理。例如,如果输入的数字非整数,应该对输入进行错误处理。 通过以上步骤,我们可以解决蓝桥杯C初级省赛的问题,并将结果输出给用户。这个例子只是为了说明题目要求,并不是实际的蓝桥杯C初级省赛题目。实际的题目可能更加复杂,需要运用更多的编程知识和技巧。通过参加蓝桥杯的比赛,可以提高自己的编程能力,增加编程经验,并锻炼解决问题的能力。同时,蓝桥杯也是一个交流和学习的平台,可以认识到更多热爱编程的同学,共同提高。 ### 回答3: 蓝桥杯C初级省赛题目是一个计算数列的问题。题目给出了一个数列的前两项和计算公式,要求根据公式计算出指定位置的数列项。 解题思路是使用循环迭代的方法,从第三项开始按照公式计算每一项,直到计算到指定位置的项。首先定义变量a和b,分别表示数列的前两项。然后使用循环迭代的方法,从第三项开始计算每一项并存储到变量temp中。计算完当前项后,将a和b的值分别更新为b和temp,即当前项变成了下一轮迭代的前两项。 根据题目要求,我们需要计算的是数列的第n项。所以在循环迭代的过程中,设置一个计数器count用来记录当前迭代的是第几项。当count等于n时,循环结束。此时temp中保存的就是数列的第n项的值。 最后,返回temp即可得到答案。 这个题目的难点在于理解并正确运用迭代的思想,以及注意处理好计数器的增加和中止条件的判断。通过仔细观察数列的规律,我们可以得到有效的计算方法,解决这道题目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值