蓝桥杯-刷题(铺地毯,多项式输出,玩具谜题,乒乓球,数字统计,明明的随机数)

铺地毯

题目描述

为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 n 张地毯,编号从 1 到 n。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。

地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。

输入格式

输入共 n+2 行。

第一行,一个整数 n,表示总共有 n 张地毯。

接下来的 n 行中,第 i+1 行表示编号 i 的地毯的信息,包含四个整数 a,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标 (a,b) 以及地毯在 x 轴和 y 轴方向的长度。

第 n+2 行包含两个整数 x 和 y,表示所求的地面的点的坐标 (x,y)。

输出格式

输出共 1 行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出 -1。

分析:

读取输入:

首先读取地毯的数量 n。

然后使用循环依次读取每张地毯的信息,即左下角坐标 (a, b) 以及在 x 轴和 y 轴方向的长度 g 和 k,通过这些信息可以确定地毯的右上角坐标为 (a + g, b + k),并将这些信息以元组或列表的形式存储在一个列表 carpets 中。

最后读取要查询的点的坐标 (x, y)。

检查覆盖情况:

从最后一张地毯(因为后铺的地毯覆盖在前面的上面)开始,也就是从列表 carpets 的最后一个元素开始向前遍历。

对于每张地毯,检查给定点的 x 坐标是否在地毯的 x 坐标范围内(即左下角的 x 坐标 a 到右上角的 x 坐标 a + g 之间),同时检查给定点的 y 坐标是否在地毯的 y 坐标范围内(即左下角的 y 坐标 b 到右上角的 y 坐标 b + k 之间)。

如果点在当前地毯的覆盖范围内,说明这就是覆盖该点的最上面的地毯,输出其编号(编号是从 1 开始的,而列表索引从 0 开始,所以输出索引 i 加 1),然后结束循环。

未找到覆盖地毯的情况:

如果循环结束后都没有找到覆盖该点的地毯,说明该点没有被任何地毯覆盖,此时输出 -1。

代码;

#include<bits/stdc++.h>

const int N= 10000 + 5;

int a[N], b[N], g[N], k[N];

int main() {

    int n, x, y;

   

    scanf("%d", &n);

    for(int i = 0; i < n; i++) {

        scanf("%d%d%d%d", &a[i], &b[i], &g[i], &k[i]);

    }

    scanf("%d%d", &x, &y);

    int ans = -1;

    for(int i = 0; i < n; i++) {

        if(x >= a[i] && y >= b[i] && x <= a[i] + g[i] && y <= b[i] + k[i]) {

            ans = i + 1;

        }

    }

    

    printf("%d\n", ans);//输出结果

    

    return 0;

}

多项式输出

题目描述

一元 n 次多项式可用如下的表达式表示:

f(x)=an​xn+an−1​xn−1+⋯+a1​x+a0​,an​=0

其中,ai​xi 称为 i 次项,ai​ 称为 i 次项的系数。给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该多项式:

-多项式中自变量为 x,从左到右按照次数递减顺序给出多项式。

-多项式中只包含系数不为 0 的项。

-如果多项式 n 次项系数为正,则多项式开头不出 + 号,如果多项式 n 次项系数为负,则多项式以 - 号开头。

-对于不是最高次的项,以 + 号或者 - 号连接此项与前一项,分别表示此项系数为正或者系数为负。紧跟一个正整数,表示此项系数的绝对值(如果一个高于 0 次的项,其系数的绝对值为 1,则无需输出 1)。如果 x 的指数大于 1,则接下来紧跟的指数部分的形式为“xb”,其中 b 为 x 的指数;如果 x 的指数为 1,则接下来紧跟的指数部分形式为 x;如果 x 的指数为 0,则仅需输出系数即可。

-多项式中,多项式的开头、结尾不含多余的空格。

输入格式

输入共有 2 行

第一行 1 个整数,n,表示一元多项式的次数。

第二行有 n+1 个整数,其中第 i 个整数表示第 n−i+1 次项的系数,每两个整数之间用空格隔开。

输出格式

输出共 1 行,按题目所述格式输出多项式。

代码

#include<bits/stdc++.h>

using namespace std;

signed main(){

int n;

cin>>n;

for(int i=n;i>=0;i--){

int x;

cin>>x;

        //x非0

if(x){

if(i!=n&&x>0)

cout<<'+';//不是第一个,才输出+

if(i!=0&&x==-1)

cout<<'-';

if(abs(x)>1||i==0)//输出系数,系数1不用输出,但是如果指数为0需要输出1

cout<<x;

            

if(i>1)//其他要输出指数

cout<<"x^"<<i;

if(i==1)//1不用输出系数

cout<<'x';

}

}

return 0;

}

生活大爆炸版石头剪刀布

题目描述

石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。在《生活大爆炸》第二季第 8 集中出现了一种石头剪刀布的升级版游戏。

升级版游戏在传统的石头剪刀布游戏的基础上,增加了两个新手势:

斯波克:《星际迷航》主角之一。

蜥蜴人:《星际迷航》中的反面角色。

这五种手势的胜负关系如表一所示,表中列出的是甲对乙的游戏结果。

现在,小 A 和小 B 尝试玩这种升级版的猜拳游戏。已知他们的出拳都是有周期性规律的,但周期长度不一定相等。例如:如果小 A 以 石头-布-石头-剪刀-蜥蜴人-斯波克 长度为 6 的周期出拳,那么他的出拳序列就是 石头-布-石头-剪刀-蜥蜴人-斯波克-石头-布-石头-剪刀-蜥蜴人-斯波克-...,而如果小 B 以 剪刀-石头-布-斯波克-蜥蜴人 长度为 5 的周期出拳,那么他出拳的序列就是 剪刀-石头-布-斯波克-蜥蜴人-剪刀-石头-布-斯波克-蜥蜴人-...。

已知小 A 和小 B 一共进行 N 次猜拳。每一次赢的人得 1 分,输的得 0 分;平局两人都得 0 分。现请你统计 N 次猜拳结束之后两人的得分。

输入格式

第一行包含三个整数:N,NA​,NB​,分别表示共进行 N 次猜拳、小 A 出拳的周期长度,小 B 出拳的周期长度。数与数之间以一个空格分隔。

第二行包含 NA​ 个整数,表示小 A 出拳的规律,第三行包含 NB​ 个整数,表示小 B 出拳的规律。其中,0 表示 剪刀,1 表示 石头,2 表示 布,3 表示 蜥蜴人,4 表示 斯波克。数与数之间以一个空格分隔。

输出格式

输出一行,包含两个整数,以一个空格分隔,分别表示小 A、小 B 的得分。

简单的模拟题

代码:

#include <iostream>

using namespace std;

int N;                  //猜拳次数int n;                //A的猜拳周期长度int m;                //B的猜拳周期长度int circle_A[205];      //A的猜拳周期int circle_B[205];      //B的猜拳周期int score_A = 0; //A的得分int score_B = 0; //B的得分int game[5][5] =        //游戏的结果情况,1表示A赢,-1表示A输,0表示平

{

{0, -1, 1, 1, -1},

{1, 0, -1, 1, -1},

{-1, 1, 0, -1, 1},

{-1, -1, 1, 0, 1},

{1, 1, -1, -1, 0}

};

int main(void){

cin >> N >> n >> m;

for(int i = 0; i < n; i++)

{

cin >> circle_A[i];

}

for(int i = 0; i < m; i++)

{

cin >> circle_B[i];

}

int i = 0;          //遍历A的猜拳周期

int j = 0;          //遍历B的猜拳周期

while(N--)

{

if(i >= n)

{

            i = 0;

}

if(j >= m)

{

            j = 0;

}

int result = game[circle_A[i]][circle_B[j]];

if(result == 1)

{

score_A++;

}

else if(result == -1)

{

score_B++;

}

i++;

j++;

}

cout << score_A << " " << score_B;

return 0;

}

玩具谜题

题目描述

小南有一套可爱的玩具小人,它们各有不同的职业。

有一天,这些玩具小人把小南的眼镜藏了起来。小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外。如下图:

这时 singer 告诉小南一个谜题:“眼镜藏在我左数第 3 个玩具小人的右数第 1 个玩具小人的左数第 2 个玩具小人那里。”

小南发现,这个谜题中玩具小人的朝向非常关键,因为朝内和朝外的玩具小人的左右方向是相反的:面朝圈内的玩具小人,它的左边是顺时针方向,右边是逆时针方向;而面向圈外的玩具小人,它的左边是逆时针方向,右边是顺时针方向。

小南一边艰难地辨认着玩具小人,一边数着:

singer 朝内,左数第 3 个是 archer。

archer 朝外,右数第 1 个是 thinker。

thinker 朝外,左数第 2 个是 writer。

所以眼镜藏在 writer 这里!

虽然成功找回了眼镜,但小南并没有放心。如果下次有更多的玩具小人藏他的眼镜,或是谜题的长度更长,他可能就无法找到眼镜了。所以小南希望你写程序帮他解决类似的谜题。这样的谜題具体可以描述为:

有 n 个玩具小人围成一圈,已知它们的职业和朝向。现在第 1 个玩具小人告诉小南一个包含 m 条指令的谜題,其中第 z 条指令形如“向左数/右数第 s 个玩具小人”。你需要输出依次数完这些指令后,到达的玩具小人的职业。

输入格式

输入的第一行包含两个正整数 n,m,表示玩具小人的个数和指令的条数。

接下来 n 行,每行包含一个整数和一个字符串,以逆时针为顺序给出每个玩具小人的朝向和职业。其中 0 表示朝向圈内,1 表示朝向圈外。保证不会出现其他的数。字符串长度不超过 10 且仅由英文字母构成,字符串不为空,并且字符串两两不同。整数和字符串之间用一个空格隔开。

接下来 m 行,其中第 i 行包含两个整数 ai​,si​,表示第 i 条指令。若 ai​=0,表示向左数 si​ 个人;若 ai​=1,表示向右数 si​ 个人。 保证 ai​ 不会出现其他的数,1≤si​<n。

输出格式

输出一个字符串,表示从第一个读入的小人开始,依次数完 m 条指令后到达的小人的职业。

简单的模拟题

代码:

#include <bits/stdc++.h>using namespace std;int main(){

int n,m;

int i,j;

int t = 0;

int op,num;

int a[100001];

string s[100001];

cin>>n>>m;

for(i = 0;i < n;i++)

cin>>a[i]>>s[i];

for(i = 0;i < m;i++)

{

cin>>op>>num;

if(a[t] == 0 && op == 0 || a[t] == 1 && op == 1)

t = t - num;

else

t = t + num;

t=(t%n+n)%n;

}

cout<<s[t];

  return 0;

}

乒乓球

题目背景

国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及。其中 11 分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役。华华就是其中一位,他退役之后走上了乒乓球研究工作,意图弄明白 11 分制和 21 分制对选手的不同影响。在开展他的研究之前,他首先需要对他多年比赛的统计数据进行一些分析,所以需要你的帮忙。

题目描述

华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在 11 分制和 21 分制下,双方的比赛结果(截至记录末尾)。

比如现在有这么一份记录,(其中 W 表示华华获得一分,L 表示华华对手获得一分):

WWWWWWWWWWWWWWWWWWWWWWLW

在 11 分制下,此时比赛的结果是华华第一局 11 比 0 获胜,第二局 11 比 0 获胜,正在进行第三局,当前比分 1 比 1。而在 21 分制下,此时比赛结果是华华第一局 21 比 0 获胜,正在进行第二局,比分 2 比 1。如果一局比赛刚开始,则此时比分为 0 比 0。直到分差大于或者等于 2,才一局结束。

注意:当一局比赛结束后,下一局立刻开始。

你的程序就是要对于一系列比赛信息的输入(WL 形式),输出正确的结果。

输入格式

每个输入文件包含若干行字符串,字符串由大写的 W 、 L 和 E 组成。其中 E 表示比赛信息结束,程序应该忽略 E 之后的所有内容。

输出格式

输出由两部分组成,每部分有若干行,每一行对应一局比赛的比分(按比赛信息输入顺序)。其中第一部分是 11 分制下的结果,第二部分是 21 分制下的结果,两部分之间由一个空行分隔。

代码:

#include<bits/stdc++.h>using namespace std;char c;string S;int n,a,b;int main(){

while(cin>>c)

{

if(c=='E')break;

S+=c;

}

for(char i:S)

{

if(i=='W')a++;

if(i=='L')b++;

if(max(a,b)>=11&&(abs(a-b)>=2))

{

cout<<a<<":"<<b<<endl;

            a=b=0;

}

}

    cout<<a<<":"<<b<<endl;

a=b=0;

cout<<endl;

for(char i:S)

{

if(i=='W')a++;

if(i=='L')b++;

        if(max(a,b)>=21&&(abs(a-b)>=2))

{

cout<<a<<":"<<b<<endl;

            a=b=0;

}

}cout<<a<<":"<<b<<endl;

return 0;

}

数字统计

题目描述

请统计某个给定范围 [L,R] 的所有整数中,数字 2 出现的次数。

比如给定范围 [2,22],数字 2 在数 2 中出现了 1 次,在数 12 中出现 1 次,在数 20 中出现 1 次,在数 21 中出现 1 次,在数 22 中出现 2 次,所以数字 2 在该范围内一共出现了 6 次。

输入格式

2 个正整数 L 和 R,之间用一个空格隔开。

输出格式

数字 2 出现的次数。

简答模拟:

代码:

#include <bits/stdc++.h>

using namespace std;

int main(){

    int a,b;

    cin>>a>>b;

    int res=0;

    for(int i=a;i<=b;i++){

        int x=i;

        while(x){

            int tmp=x%10;

            if(tmp==2)res++;

            x/=10;

        }

    }

    cout<<res;

}

明明的随机数

题目描述

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N 个 1 到 1000 之间的随机整数 (N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

输入格式

输入有两行,第 1 行为 1 个正整数,表示所生成的随机数的个数 N。

第 2 行有 N 个用空格隔开的正整数,为所产生的随机数。

输出格式

输出也是两行,第 1 行为 1 个正整数 M,表示不相同的随机数的个数。

第 2 行为 M 个用空格隔开的正整数,为从小到大排好序的不相同的随机数。

代码:

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

const int N = 100010;int a[N];int n;

// 快读函数inline int read() {

    int x = 0, f = 1;

    char ch = getchar();

    while (ch < '0' || ch > '9') {

        if (ch == '-') f = -1;

        ch = getchar();

    }

    while (ch >= '0' && ch <= '9') {

        x = (x << 3) + (x << 1) + (ch ^ 48);

        ch = getchar();

    }

    return x * f;

}

// 三数取中选择基准元素int medianOfThree(int* a, int l, int r) {

    int mid = l + (r - l) / 2;

    if (a[l] > a[mid]) std::swap(a[l], a[mid]);

    if (a[l] > a[r]) std::swap(a[l], a[r]);

    if (a[mid] > a[r]) std::swap(a[mid], a[r]);

    std::swap(a[l], a[mid]);  // 将中位数放到最左边

    return a[l];

}

// 分区函数int part(int* a, int l, int r) {

    int k = medianOfThree(a, l, r);

    int L = l + 1, R = r;

    while (true) {

        while (L <= r && a[L] < k) L++;

        while (a[R] > k) R--;

        if (L >= R) break;

        std::swap(a[L], a[R]);

        L++;

        R--;

    }

    std::swap(a[l], a[R]);

    return R;

}

// 快速排序函数void quickSort(int* a, int l, int r) {

    if (l >= r) return;

    int k = part(a, l, r);

    quickSort(a, l, k - 1);

    quickSort(a, k + 1, r);

}

int main() {

    n = read();

    unordered_map<int,int> e;

    int m=0;

    for (int i = 0; i < n; i++) {

        a[i] = read();

        if(!e[a[i]])m++;

        e[a[i]]=1;

        

    }

    cout<<m<<endl;

    quickSort(a, 0, n - 1);

    int pre=-1;

    for (int i = 0; i < n; i++) {

        if(a[i]==pre)continue;

        

        if (i > 0) printf(" ");

        printf("%d", a[i]);

        pre=a[i];

    }

    printf("\n");

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值