2018 蓝桥杯省赛 B 组模拟赛(一)

A

题目

今天蒜头君带着花椰妹和朋友们一起聚会,当朋友们问起年龄的时候,蒜头君打了一个哑谜(毕竟年龄是女孩子的隐私)说:“我的年龄是花椰妹年龄个位数和十位数之和的二倍”。

花椰妹看大家一脸懵逼,就知道大家也不知道蒜头君的年龄,便连忙补充道:“我的年龄是蒜头君个位数和十位数之和的三倍”。

请你计算:蒜头君和花椰妹年龄一共有多少种可能情况?

提醒:两位的年龄都是在 [10,100)[10,100) 这个区间内。

代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int ans=0;
    for(int i=10;i<100;i++)
    {
        int m=2*(i%10+i/10);
        int n=0;
        if(m>=10&&m<100)
        {
            n=3*(m%10+m/10);
            if(n==i)
                ans++;
        }
    }
    printf("%d",ans);
    return 0;
}

遍历10~100,假设花椰妹年龄为i,根据花椰妹年龄求出蒜头君年龄,在判断是否符合题意即可。

B

题目

蒜头君今天回到了老家的大宅院,老家的灯还是那中拉线的灯(拉一次为亮,再拉一次就灭),蒜头君觉得无聊。把 1000 盏灯 3 的倍数拉了一次,5 的倍数拉了一次,7的倍数拉了一次(灯得的编号从 1-1000,灯的初始状态都是亮的)。这个时候蒜头君在想还剩下几盏灯还在亮着?

提示:请不要输出多余的符号

代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int ans=0;
    int l[1005];
    for(int i=0;i<1005;i++)
        l[i]=1;
    for(int i=0;i<1000;i++)
    {
        if(i%3==0)
        {
            if(l[i]==0)
                l[i]=1;
            else
                l[i]=0;
        }
        if(i%5==0)
        {
            if(l[i]==0)
                l[i]=1;
            else
                l[i]=0;
        }
        if(i%7==0)
        {
            if(l[i]==0)
                l[i]=1;
            else
                l[i]=0;
        }
    }
    for(int i=0;i<1000;i++)
    {
        if(l[i]==1)
            ans++;
    }
    printf("%d",ans);
    return 0;
}

遍历1~1000直接模拟即可

C

题目

最近蒜头君喜欢上了U型数字,所谓U型数字,就是这个数字的每一位先严格单调递减,后严格单调递增。比如 212 就是一个U型数字,但是 333, 98, 567, 31313,就是不是U型数字。

现在蒜头君问你,[1,100000]有多少U型数字?

提示:请不要输出多余的符号。

代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int l[10];
    int ans=0;
    for(int i=101;i<100000;i++)
    {
        memset(l,0,sizeof(l));
        int j=0;
        int a=i;
        while(a!=0)
        {
            l[j++]=(a%10);
            a/=10;
        }//printf("%d\n",j);
        int flag=0,flag1=0,flag2=0;
        for(int k=0;k<j-1;k++)
        {
            if(l[k]>l[k+1]&&flag2==0)          //在递增之前先递减。
            {
                flag1=1;
            }
            else if(l[k]<l[k+1]&&flag1==1)             //递减之后递增 。
            {
                flag2=1;;
            }
            else flag=1;        //出现其他情况侧则不是。
        }
        //printf("%d\n",flag);
        if(flag==0&&flag1==1&&flag2==1)
            ans++;
    }
    printf("%d",ans);
    return 0;
}

由题意知,1~100之间没有U型数字,所以从101开始遍历,找到一个ans加 1。

D

题目

LIS是最长上升子序列。什么是最长上升子序列? 就是给你一个序列,请你在其中求出一段最长严格上升的部分,它不一定要连续。

就像这样:22, 33, 44, 77 和 22, 33, 44, 66 就是序列 22 55 33 44 11 77 66 的两个上升子序列,最长的长度是 44。

代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int N;
int arr[1005],dp[1005];
int mmp()
{
    int ans=1;
    for(int i=1;i<=N;i++)
    {
        dp[i]=1;
        for(int j=1;j<i;j++)
        {
            if(arr[j]<arr[i])            //每进行一次循环,dp[i]都会变为当前最大的递增子序列。
                dp[i]=max(dp[j]+1,dp[i]);
        }
        ans=max(ans,dp[i]);          //找出N组递增子序列中最大的即可。
    }
    return ans;
}
int main()
{
    scanf("%d",&N);
    for(int i=1;i<=N;i++)
        scanf("%d",&arr[i]);
    int ans=mmp();
    printf("%d\n",ans);
    return 0;
}

这是原来的代码,用计蒜客上的AC代码好像有点子问题。

E

题目

相信大家都知道什么是全排列,但是今天的全排列比你想象中的难一点。我们要找的是全排列中,排列结果互不相同的个数。比如:aab 的全排列就只有三种,那就是aab,baa,aba。

代码框中的代码是一种实现,请分析并填写缺失的代码。

代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e3;
char str[N], buf[N];//buffer
int vis[N], total, len;
void arrange(int num)
{
    if (num == len)
    {
        printf("%s\n", buf);
        total++;
        return;
    }
    for (int i = 0; i < len; ++i)
    {
        if (!vis[i])
        {
            int j;
            for (j = i + 1; j < len; ++j)
            {
                if (str[i]==str[j]&&vis[j])            //如果出现重复字符则break
                {
                    break;
                }
            }
            if (j == len)
            {
                vis[i] = 1;
                buf[num] = str[i];
                arrange(num + 1);
                vis[i] = 0;             //回溯。
            }
        }
    }
}
int main()
{
    while (~scanf("%s",str))
    {
        len = strlen(str);
        sort(str, str + len);
        total = 0;
        buf[len] = '\0';
        arrange(0);
        printf("Total %d\n", total);
    }
    return 0;
}

F

题目

蒜头君今天突然开始还念童年了,想回忆回忆童年。他记得自己小时候,有一个很火的游戏叫做数独。便开始来了一局紧张而又刺激的高阶数独。蒜头君做完发现没有正解,不知道对不对? 不知道聪明的你能否给出一个标准答案?

标准数独是由一个给与了提示数字的 9×9 网格组成,我们只需将其空格填上数字,使得每一行,每一列以及每一个 3×3 宫都没有重复的数字出现。
在这里插入图片描述
输出这个数独得正解,输出格式如下:

* 2 6 * * * * * *
* * * 5 * 2 * * 4
* * * 1 * * * * 7
* 3 * * 2 * 1 8 *
* * * 3 * 9 * * *
* 5 4 * 1 * * 7 *
5 * * * * 1 * * *
6 * * 9 * 7 * * *
* * * * * * 7 5 *

把上面的 * 替换成 1 - 91−9 就可以了

提醒:两个数字之间要有一个空格,其他地方不要输出多余的符号。

代码
//这个题是百度出来的。
#include <bits/stdc++.h>
#define M 11
using namespace std;
struct point
{
    int x, y;
} p[100];
bool flag, row[M][M], col[M][M], mat[3][3][M];
int np = 0;
int Map[M][M]= {
{0,2,6,0,0,0,0,0,0},
{0,0,0,5,0,2,0,0,4},
{0,0,0,1,0,0,0,0,7},
{0,3,0,0,2,0,1,8,0},
{0,0,0,3,0,9,0,0,0},
{0,5,4,0,1,0,0,7,0},
{5,0,0,0,0,1,0,0,0},
{6,0,0,9,0,7,0,0,0},
{0,0,0,0,0,0,7,5,0}};
void dfs(int n)
{
    if(flag)
        return;
    if(n == -1)             //当模拟的答案正确时输出。
    {
        for(int i=0;i<9 && !flag;i++)
        {
            for(int j=0;j<9;j++)
                printf("%d ",Map[i][j]);
            printf("\n");
        }
        flag = 1;         //题目只要一种正确情况。
        return;
    }
    for(int i=1;i<=9 && !flag;i++)
    {
        int x = p[n].x;
        int y = p[n].y;
        if(!row[x][i] && !col[y][i] && !mat[x/3][y/3][i])
        {
            row[x][i] = col[y][i] = mat[x/3][y/3][i] = true;
            Map[x][y] = i;
            dfs(n-1);            //递归搜索
            Map[x][y] = 0;
            row[x][i] = col[y][i] = mat[x/3][y/3][i] = false;           //回溯
        }
    }
}
int main()
{
    flag = 0;
    memset(row,false,sizeof(row));           //全部初始化。
    memset(col,false,sizeof(col));
    memset(mat,false,sizeof(mat));
    for(int i=0;i<9;i++)
    {
        for(int j=0;j<9;j++)
        {
            int num = Map[i][j];
            if(num)
            {
                row[i][num] = col[j][num] = mat[i/3][j/3][num] = true;          //标记原来已有数据。
            }
            else
            {
                p[np].x = i;
                p[np++].y = j;
            }
        }
    }
    dfs(np-1);
    return 0;
}

G

题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
    double l[1005],arr[1005];
    int n;
    cin>>n;
    cin>>arr[0]>>arr[n+2];
    for(int i=1;i<=n;i++)
    {
        cin>>l[i];
    }
    arr[1]=0;
    for(int i=2;i<=n+1;i++)
    {
        arr[i]=2*(arr[i-1]+l[i-1])-arr[i-2];
    }
    double ans=(arr[n+2]-arr[n+1])/(n+1);
    printf("%.2lf",ans);
    return 0;
}

H

题目

蒜头君被暗黑军团包围在一座岛上,所有通往近卫军团的路都有暗黑军团把手。幸运的是,小岛上有一扇上古之神打造的封印之门,可以通往近卫军团,传闻至今没有人能解除封印。

封印之门上有一串文字,只包含小写字母,有 k 种操作规则,每个规则可以把一个字符变换成另外一个字符。经过任意多次操作以后,最后如果能把封印之门上的文字变换成解开封印之门的文字,封印之门将会开启。

蒜头君战斗力超强,但是不擅计算,请你帮忙蒜头君计算至少需要操作多少次才能解开封印之门。

输入格式
输入第一行一个字符串,长度不大于 1000,只包含小写字母,表示封印之门上的文字。

输入第二行一个字符串,只包含小写字母,保证长度和第一个字符串相等,表示能解开封印之门的文字。

输入第三行一个整数 k(0≤k≤676)。

接下来 k 行,每行输出两个空格隔开的字符 a, bb,表示一次操作能把字符 a变换成字符 b。

输出格式
如果蒜头君能开启封印之门,输出最少的操作次数。否则输出一行 −1。

代码
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3fffffff
int main()
{
    int l[30][30];
    for(int i=0;i<26;i++)
    {
        for(int j=0;j<26;j++)
        {
            if(i==j)
            {
                l[i][j]=0;
            }
            else
            {
                l[i][j]=inf;
            }
           // cout<<l[i][j]<<" ";
        }
        //cout<<endl;
    }
    int n;
    string s1,s2;
    char a,b;
    cin>>s1>>s2;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a>>b;
        if(a!=b)
            l[a-'a'][b-'a']=1;
    }
    for(int i=0;i<26;i++)
    {
        for(int j=0;j<26;j++)
        {
            for(int k=0;k<26;k++)
            {
                //cout<<l[j][k]<<endl;
                l[j][k]=min(l[j][k],l[j][i]+l[i][k]);
                //cout<<l[j][k]<<endl;
            }
        }
    }

    int sum=0;
    for(int i=0;i<s1.size();i++)
    {
        if(l[s1[i]-'a'][s2[i]-'a']>=inf)
        {
            sum=-1;
            break;
        }
        else
        {
            sum+=l[s1[i]-'a'][s2[i]-'a'];
           // cout<<l[s1[i]-'a'][s2[i]-'a']<<endl;
        }
    }
    cout<<sum;
    return 0;
}

这个题类似于之前比赛时遇到的迪克斯特拉算法,详见博客凯迪克斯拉

I

题目

在一个星光摧残的夜晚,蒜头君一颗一颗的数这天上的星星。

蒜头君给在天上巧妙的画了一个直角坐标系,让所有的星星都分布在第一象。天上有 n 颗星星,他能知道每一颗星星的坐标和亮度。

现在,蒜头君问自己 q 次,每次他问自己每个矩形区域的星星的亮度和是多少(包含边界上的星星)。
在这里插入图片描述
输入格式
第一行输入一个整数 n(1≤n≤50000) 表示星星的数量。
接下里 nn 行,每行输入三个整数 x,y,w(0≤x,y,w≤2000),表示在坐标 (x,y) 有一颗亮度为 w 的星星。注意一个点可能有多个星星。
接下来一行输入一个整数 q(1≤q≤50000),表示查询的次数。

接下来 qq 行,每行输入四个整数 x1 ,y1,x2,y2,其中 (x1,y1) 表示查询的矩形的左下角的坐标,(x2,y2) 表示查询的矩形的右上角的坐标,0≤x1≤x2 ≤2000,0≤y1≤y2≤2000。
输出格式
对于每一次查询,输出一行一个整数,表示查询的矩形区域内的星星的亮度总和。
样例输入

5
5 0 6
7 9 7
8 6 13
9 7 1
3 0 19
4
0 8 7 9
0 0 7 10
2 7 10 9
5 4 7 5

样例输出

7
32
8
0
代码

用二维数组表示某位置之前的亮度总和,再用求前缀和的方法解决,类似于求大矩形中小矩形的面积。

#include<bits/stdc++.h>
using namespace std;
int l[2005][2005];
int main()
{
    int n;

    int x,y,w;
    memset(l,0,sizeof(l));
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>x>>y>>w;
        l[x+1][y+1]+=w;
    }
    for(int i=1;i<2005;i++)
    {
        for(int j=1;j<2005;j++)
        {
            l[i][j]+=l[i-1][j]+l[i][j-1]-l[i-1][j-1];
        }
    }
    int q,x1,x2,y1,y2;
    cin>>q;
    int sum=0;
    for(int i=0;i<q;i++)
    {
        sum=0;
        cin>>x1>>y1>>x2>>y2;
        sum=l[x2+1][y2+1]+l[x1][y1]-l[x2+1][y1]-l[x1][y2+1];
        cout<<sum<<endl;
    }
    return 0;
}

J

看不懂T^T

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值