1.14食油大学acm训练赛NO.6

一系列编程题目涉及到计算平均值、射击游戏策略、找丢失颜色的画笔、拨算盘次数、打印特定图形、数列计算、完全平方数、字符串处理、学习用品花费统计、素数对寻找、图形变换和数字转换。这些问题涵盖了数据处理、逻辑推理和算法设计等多个方面。
摘要由CSDN通过智能技术生成

问题 A: 平均值I
题目描述
豆豆从小对数字很敏感,小学里就显露出超常的能力,老师为了防止他太过骄傲,给了他一个可怕的难题:求一串给定整数某一段的平均值,保留3位小数。每个整数都是小于231的。老师做梦也没想到豆豆全都回答出来了,原来豆豆有一个擅长编程的朋友你。

输入
第一行一个整数N(1<=N<=100000),表示一串整数的个数;
第二行用空格隔开的N个非负整数;
第三行一个整数M(1<=M<=100000),表示M次询问;
接下来M行,每行两个整数i和j(1<=i,j<=N),表示询问第i个到第j个整数的平均值,不保证i<j。
输出
M行,每行一个小数,表示平均值,要求小数点后面保留3位输出。
样例输入 Copy
5
0 25 0 23 2
1
1 5
样例输出 Copy
10.000
提示
数据保证N个整数和小于263

简单的前缀和问题。用第二个数组存第一个数组的前n项和

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long int n,m,a[100010],i,b[100010];
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    b[1]=a[1];
    for(i=2;i<=n;i++)
    {
        b[i]=a[i]+b[i-1];
    }
    int x,y;
    scanf("%d",&m);
    for(i=0;i<m;i++)
    {
        scanf("%d%d",&x,&y);
        if(x>y)
        {
            swap(x,y);
        }
        double z=b[y]-b[x-1];
        printf("%.3f\n",z*1.0/(y-x+1)*1.0);
    }
}

问题 B: 射击
题目描述
不难发现,eason能从很多事情中去思考数学,于是eason父母决定让他去练习射击,这是项需要集中注意力的运动,相信能够让eason暂时脱离数学。学习射击的第一天就让eason产生了浓厚的兴趣,射击的靶子是大饼圆,射击枪的子弹近似圆柱,为什么要圆的不能是其他的形状呢,于是eason开始构思,设计了这样一个好玩的问题:
N*M 的方形格子靶子,每个格子有两种状态凸或者凹(如下图浅色表示凹,深色表示凸)
在这里插入图片描述

现在用一个十字横截面的子弹(填充黑色部分)去射击,被射中的小格子凹变凸,凸变凹,子弹放大后的横截面如下图
在这里插入图片描述

这种子弹最多可以覆盖 5 个格子,如图打完后,5 个格子凹凸状态发生了变化
在这里插入图片描述

请问最少需要几次射击使靶子中所有小格子都呈现凹的状态。
注意:子弹中心点如果打到四个角上则只会影响 3 个格子,如下图黑色格子表示被子弹中心点正好击中左上角后覆盖的 3 个格子,如果打到除四个角的边界上,则会影响到 4 个格子,如下图右侧的 4 个黑色格子所示,这是子弹中心点打中第 3 行第 6 列时的覆盖情况。(也就是说子弹超出靶子部分不起效)
在这里插入图片描述

输入
第一行两个用空格隔开的数字 N 和 M(1<=N,M<=17)
接下来 N 行描述靶子中小格子的状态,‘X’表示凸,‘.’表示凹。

输出
输出所需要的最少射击次数
注意:输入数据保证有解

样例输入 Copy
5 5
XX.XX
X.X.X
.XXX.
X.X.X
XX.XX
样例输出 Copy
5

有待解决

问题 C: 找画笔
题目描述
Cherrydjt对数字的执着,让他在理科领域游刃有余,但他近乎疯狂的投入也使父母有些担心,为了让孩子能够全面发展,决定拓宽他的学习领域,正好家旁边有个绘画培训中心就给Cherrydjt报了名,学习绘画的第一天就让Cherrydjt产生了浓厚的兴趣,还主动要求买了很多很多的画笔,画笔有多种颜色,Cherrydjt有一个习惯就是同种颜色的画笔就买两支,一支备用,就这样总共攒了N支画笔(N是偶数且1<N<10^6)。 可是数字的敏感无孔不入,Cherrydjt脑里蹦出了一个奇怪的问题:如果蒙上眼任意拿走一支画笔,分析剩下的N-1支画笔找出拿走了哪种颜色,你能回答他吗?
输入
第一行一个整数表示剩下的画笔个数就是题目描述中的N-1
第二行N-1个用空格隔开的正整数Ai(1<=Ai<231),表示剩下的画笔的颜色编号

注意:数据保证有一个画笔的颜色编号出现了一次,其余的都出现了两次

输出
一行一个整数P,表示拿走的画笔的颜色编号。
样例输入 Copy
9
1 1 9 11 5 3 11 5 9
样例输出 Copy
3

这个题如果想a[x]++然后找为1的值的话会爆掉,所以就给输入的数排序,每两个两个判断是否相等

#include<bits/stdc++.h>
using namespace std;
int n,a[1000010];
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
    }
    sort(a+1,a+n+1);
    for(int i=1; i<=n; i+=2)
    {
        if(a[i]!=a[i+1])
        {
            cout<<a[i];
            return 0;
        }
    }
}

问题 D: 拨算盘
题目描述
对数字敏感的豆豆顺利进入了学校的珠算兴趣小组,老师送了他们每人一个算盘,但好玩的算盘并不是那么容易上手的,有很多小朋友因为嫌累纷纷退出了该兴趣小组,豆豆觉得人都走光了就太冷清了,于是决定说服小朋友们留下来,他把加法算式所需要的拨动次数算了出来,发现其实拨动次数没有想象的那么多。
现在给你一系列加数(正整数),请计算使用算盘求解时需要拨动几次,(算盘图如下,当前表示67)
在这里插入图片描述

算盘被中间的横档分为上下半区,上方只有1颗表示该位上的5,靠近中间的横档就计数5,只要拨动它就累计一次拨动,下方的四颗每颗表示1,靠近横档就计相应个数的1,下方需要拨动多颗可以合并为一次拨动。
注意:珠算里面的手法习惯是高位先算(这迎合了我们读数字的习惯)例如37+31,拨动方法如下图:
在这里插入图片描述

所以37+31总共需要拨动6次
输入
第一行一个整数 N(1<=N<=10000),表示加数的个数 接下来 N 行,每行一个正整数,表示加数 Ai(1<=Ai<231)
输出
一个整数表示需要的拨动次数(假设算盘的位数足够多,不止图上的19位)
样例输入 Copy
2
26
37
样例输出 Copy
8
提示
30%的数据保证每个加数是 100 以内的,N<=10
60%的数据保证加数和小于 2^31,N<=100

有待解决

问题 E: 打印图形V
题目描述
由键盘输入任意一个自然数N,输出如下图规律的图形。
输入
只有一个整数N,为图形的行数(其中2<=N<=26)
输出
输出指定格式的图形。
样例输入 Copy
4
样例输出 Copy
在这里插入图片描述

这个题我分成了四部分输出。看代码应该就可以理解了

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,i,j;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n-i;j++)
        {
            cout<<" ";
        }
        for(char ch=char('A'+n-1);ch>=(char)('A'+n-i);ch--)
        {
            cout<<ch;
        }
        for(char ch=(char)('A'+n-i+1);ch<=char('A'+n-1);ch++)
        {
            cout<<ch;
        }
        cout<<endl;
    }
    for(i=n-1;i>=1;i--)
    {
        for(j=1;j<=n-i;j++)
        {
            cout<<" ";
        }
        for(char ch=char('A'+n-1);ch>=(char)('A'+n-i);ch--)
        {
            cout<<ch;
        }
        for(char ch=(char)('A'+n-i+1);ch<=char('A'+n-1);ch++)
        {
            cout<<ch;
        }
        cout<<endl;
    }
}

问题 F: 数列计算IV
题目描述
有一个分数序列是:1/2,2/3,3/5,5/8,8/13,13/21… …,请同学们认真观察好分子和分母的规律。现要求:指定项数为任意的N项,请输出前N项。
输入
只有一行,包含1个整数N(其中2≤N≤20)为这个分数序列的项数。
输出
请输出这个分数序列的分数形式(请注意显示形式突出序列变化的规律,所以不用化简)。
样例输入 Copy
6
样例输出 Copy
1/2 2/3 3/5 5/8 8/13 13/21
水题

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,a[30],b[30];
    int i;
    cin>>n;
    a[0]=1;
    b[0]=2;
    a[1]=2;
    b[1]=3;
    cout<<a[0]<<"/"<<b[0]<<" ";
    cout<<a[1]<<"/"<<b[1]<<" ";
    for(i=2;i<n;i++)
    {
        a[i]=a[i-1]+a[i-2];
        b[i]=b[i-1]+b[i-2];
        cout<<a[i]<<"/"<<b[i]<<" ";
    }
}

问题 G: 完全平方数II
题目描述
一个数如果是另一个整数的完全平方,那么我们就称这个数为完全平方数。如25,36,49,……121,144,225,361,400,441,484,……961等。现要求在三位整数中找出具有这样一些特点的数:
(1)它们是完全平方数;
(2)三位数字中有两位数字相同。
例如144、225、400、676等。
求出任意自然数M ~N之间所有满足上述条件的数,并统计这样的数的个数。

输入
只有一行,包含两个用空格隔开的任意自然数M和N(其中100<=M<N<=999)。
输出
共有若干行:前若干行每行一个整数是任意自然数M~N之间所有满足条件的平方数;最后一行是统计这些平方数的个数。若没有满足条件的完全平方数,直接输0。
样例输入 Copy
100 300
样例输出 Copy
100
121
144
225
4

也是水题,看好条件就好

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int m,n,i,flag=0,cnt=0;
    cin>>m>>n;
    int a,b,c;
    for(i=m;i<=n;i++)
    {
        a=i/100;
        b=i%100/10;
        c=i%10;
        int k=sqrt(i);
        if(k*k==i)
        {
            if(a==b||b==c||c==a)
            {
                cout<<i<<endl;
                flag=1;
                cnt++;
            }
        }
    }
    if(flag)
    {
        cout<<cnt;
    }
    else
    {
        cout<<"0";
    }
}

问题 H: 海淀字符串III
题目描述
从键盘输入一个长度不大于20的字符串,现要求:将字符串中的小写字母都改成相应的大写字母,其他字符依照原有顺序不变。
输入
只有一行,包含1个任意的字符串(其长度1<=L<=20)
输出
只有一行,即为:把小写字母改成相应的大写字母,其他字符依照原有顺序不变的字符串。
样例输入 Copy
ABCD123.eeffDD
样例输出 Copy
ABCD123.EEFFDD

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string c;
    cin>>c;
    int i;
    for(i=0;c[i]!='\0';i++)
    {
        if(c[i]<='z'&&c[i]>='a')
        {
            c[i]=char(c[i]-32);
        }
        cout<<c[i];
    }
}

问题 I: 用品
题目描述
只有一行,即为:把小写字母改成相应的大写字母,其他字符依照原有顺序不变的字符串。

已知:笔记本每本2元,铅笔每支0.5元,橡皮每块0.8元,圆珠笔每支2.5元。
现在请你计算一下:1) 每位同学合计花了多少元(如果有小数,最后结果下取整即可)?
2)N名同学购买学习用品平均花费的钱数是多少元(如果有小数,最后结果下取整即可)?
3)统计N名同学中哪些同学购买学习用品的花费低于平均花费(注意是低于实际平均花费,并非上面的显示值)?
在这里插入图片描述

输入
第一行有一个整数N,表示有N名同学,已知2≤N≤10;
以下有5*N行数据,每5行代表一个人的信息记录(包括学生的姓名及购买4种学习用品的数量,其中4种学习用品的数量都为不大于50的整数)。
输出
共有若干行:
前N行:每行一个数据是每位同学合计所花的钱数(按照取整显示);
之后的一行:是N名同学平均花费的钱数(每人花费取整后总和再平均);
最后若干行:每行一个数据是N名同学中低于平均花费的学生姓名(低于低于实际平均花费的人名)。
按输入顺序输出
样例输入 Copy
3
zhangfang
5
10
6
3
lihao
8
12
2
3
wanghong
6
8
4
3
样例输出 Copy
27
31
26
28
zhangfang
wanghong

结构体

#include<bits/stdc++.h>
using namespace std;
struct node
{
    string id;
    int a;
    int b;
    int c;
    int d;
    int sum;
}s[20];
int main()
{
    int n;
    int i;
    double sum=0;
    cin>>n;
    for(i=0;i<n;i++)
    {
        cin>>s[i].id>>s[i].a>>s[i].b>>s[i].c>>s[i].d;
        s[i].sum=s[i].a*2+s[i].b*0.5+s[i].c*0.8+s[i].d*2.5;
        cout<<floor(s[i].sum)<<endl;
        sum+=s[i].sum;
    }
    cout<<floor(sum*1.0/n)<<endl;
    for(i=0;i<n;i++)
    {
        if(s[i].sum<sum/n)
        {
            cout<<s[i].id<<endl;
        }
    }
}

问题 J: 海淀素数
题目描述
在三位自然数中有这样一些特点的数:
(1)它们是素数;
(2)它们中满足:任意两个素数的和小于1000,同时又是17的倍数。
如:227和283,229和281,233和277等等。
求出任意自然数M ~N之间所有满足上述条件的素数对,并统计素数对的个数。

输入
只有一行,包含两个用空格隔开的任意自然数M和N(其中100<=M<N<=999)。

输出
共有若干行:
前若干行每行为一对满足条件的素数对(数据之间空1格);
最后一行是统计这些素数对的个数。如果没有则只输出0即可。

样例输入 Copy
200 300
样例输出 Copy
227 283
229 281
233 277
239 271
241 269
251 293
263 281
7

#include<bits/stdc++.h>
using namespace std;
int prime(int m)
{
    int i,k;
    if(m==1)
    return 0;
    for(i=2;i*i<=m;i++)
    {
        if(m%i==0)
        return 0;
    }
    return 1;
}
int main()
{
    int m,n,i,cnt=0,flag=0;
    int j;
    cin>>m>>n;
    for(i=m;i<=n;i++)
    {
        for(j=i;j<=n;j++)
        {
            if(prime(i)==1&&prime(j)==1)
            {
                if((i+j)%17==0&&i+j<1000)
                {
                    cout<<i<<" "<<j<<endl;
                    cnt++;
                    flag=1;
                }
            }
        }
    }
    if(flag)
    {
        cout<<cnt;
    }
    else
    {
        cout<<"0";
    }

}

问题 K: 乐乐的图形
题目描述
乐乐最近玩起了字符游戏,规则是这样的:读入四行字符串,其中的字母都是大写的,乐乐想打印一个柱状图显示每个大写字母的频率。你能帮助她吗?
输入
共有4行:每行为一串字符,不超过72个字符。
输出
与样例的格式保持严格的一致。
样例输入 Copy
THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG.
THIS IS AN EXAMPLE TO TEST FOR YOUR
HISTOGRAM PROGRAM.
HELLO!
样例输出 Copy
在这里插入图片描述

提示
1.输出的相邻字符间有一个空格。
2.最后一行的26个大写字母每次必须输出。
3.大写字母A所在的第一列前没有空格。

这个和昨天的股价图类似

#include<bits/stdc++.h>
using namespace std;
int a[300];
int main()
{
    int n,max1=-1,i,j,l;
    string s;
    for(i=1; i<=4; i++)
    {
        getline(cin,s);
        l=s.length();
        for(j=0; j<l; j++)
        {
            if(s[j]>='A'&&s[j]<='Z')
            {
                a[s[j]-'A']++;
                max1=max(max1,a[s[j]-'A']);
            }
        }
    }
    for(i=max1; i>=1; i--)
    {
        for(j=0; j<=25; j++)
        {
            if(a[j]>=i)
            {
                cout<<"*";
            }
            else
            {
                cout<<" ";
            }
            cout<<" ";
        }
        cout<<endl;
    }
    for(i=0; i<26; i++)
    {
        cout<<char('A'+i)<<" ";
    }
}

问题 L: 乐乐的数字
题目描述
乐乐做完数学作业,突发奇想定义了一种新的数:乐乐数。乐乐把n个数排成一行,一个数的“乐乐数”是指:在这个数的左边且比它小的数中最靠近它(即最靠右)的那个数。依次给出这n个数,请求出所有这n个数相对应的“乐乐数”。
输入
第一行是一个正整数n,表示一共有多少个数。
第二行有n个用空格隔开的正整数,它们从左至右给出了数列中的n个数。这些数保证小于231。
输出
输出一行用空格隔开的n个数。
这些数对应于输入数据中的数的“乐乐数”。如果输入中某个数没有“乐乐数”(即它左边的数都不比它小),请输出0。

样例输入 Copy
7
3 1 2 7 6 7 4
样例输出 Copy
0 0 1 2 2 6 2
提示
对于80%的数据,n≤10000;
对于100%的数据,n≤200000。

有待解决

问题 M: 乐乐的棋盘
题目描述
乐乐有一个棋盘,共有m行n列,一只棋子从左上角开始,向右下角移动,每次只能向下或向右移动一次。然而这个棋盘中有一些障碍物,这些障碍物使得这个棋子不能进入这些格子,问这个棋子从左上角到达右下角共有多少种不同的移法?如果到达不了,则输出0。

输入
第一行:两个整数m,n,0<m,n≤100。
后面有m行,每行有n个数(0或1),如果是1,则表示这个方格中有障碍物。

输出
求得的方案数。
样例输入 Copy
4 5
0 0 1 0 0
0 1 0 0 0
0 0 0 0 0
0 1 0 0 0
样例输出 Copy
3
提示
对于80%的数据,0<m,n<20;
对于100%的数据,0<m,n≤100。

有待解决

问题 N: 乐乐的方块
题目描述
乐乐被小学数学课本中“空间与图形”的内容迷住了,她整天在琢磨着图形的各种变换:对称、旋转、翻转等等。这天,乐乐用“@”和“-”两种字符拼成了一块N x N(1≤N≤20)的方形图案A,现在她想将其转换成新的方形图案B。有以下几种转换方法:
方法1:转90度:图案按顺时针转90度。
方法2:转180度:图案按顺时针转180度。
方法3:转270度:图案按顺时针转270度。
方法4:反射:图案在水平方向翻转。
方法5:组合:图案在水平方向翻转,然后再按照1到3之间的一种再次转换。
方法6:不改变:原图案不改变。
方法7:无效转换:无法用以上方法得到新图案。
只能选择上述7种方法中的某一种来转换图案。例如有如下一个3*3的图案A:

@-@

@-@
要转换成图案B:
@-@

@-@
按照上述的方法,有方法1、方法2、方法3、方法4、方法5和方法6共六种方法可以实现这种转换。你只需要输出:1,表示采用序号最小的方法。
你能帮助乐乐写一个程序,来解决这个难题吗?

输入
第1行:单独的一个整数N。
第2行到第N+1行:每行N个字符(不是“@”就是“-”);这是转换前的方块图案。
第N+2行到第2*N+1行:每行N个字符(不是“@”就是“-”);这是转换后的方块图案。

输出
单独的一行包括1到7之间的一个数字,表明需要将转换前的方块变为转换后的方块的转换方法(序号最小者)。
样例输入 Copy
3
@-@

@@-
@-@
@–
–@
样例输出 Copy
1

待解决
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值