上海大学2020年夏季程序实习OJ平台练习题目记录
前五道题为标准答案,后五道自己写的
1 阶乘尾部0的个数
问题描述 给定非负整数n,计算n的阶乘尾部0的个数。
输入 输入数据有若干行,每行上有一个非负整数n,对应一种情形。
输出 对于每一种情形,直接输出结果、换行。
输入样例
8
16
30
输出样例
1
3
7
#include <stdio.h>
int zeros(int n)
{
int m=0, p=5;
while(p<=n)
{
m += n/p;
p *= 5; // p的变化规律为5的1,2,3,…次方
}
return m;
}
int main()
{
// fact(22);return 0; // 用于测试fact何时溢出
int n;
while(scanf("%d", &n)==1){ // scanf函数的返回值是其读取到的数据个数
printf("%d\n", zeros(n));
}
return 0;
}
2 判断算式的正确性
问题描述 给定一个算式,该算式中只含一个四则运算符号,操作数及结果均为整数。要求判断该算式的正确性(规定:除法必须除尽才算正确)。
输入 输入数据有若干行,每行上有一个算式,对应一种情形。
输出 对于每一种情形,直接输出T(表示正确)或F(表示错误),换行。
输入样例
1 + 2 = -3
5 / 2 = 2
4 / 2 = 2
输出样例
F
F
T
int main()
{
int x, y , z;
char op, eq;
while(scanf("%d %c %d %c %d", &x, &op, &y, &eq, &z)==5)
{ // 直接接收5个输入的数据,数据类型不尽相同
if( (op=='+' && x+y==z)
|| (op=='-' && x-y==z)
|| (op=='*' && x*y==z)
|| (y!=0 && x%y==0 && x/y==z) )
printf("T\n");
else
printf("F\n");
}
return 0;
}
3 计算一系列实数的个数、最小值、最大值和“平均值”
问题描述 给定若干个(大于0且不超过1024)实数,计算其中数据的个数(n)、最小值、最大值,以及“平均值”。此处的“平均值”定义为,若n>2,则需去掉一个最大值、一个最小值,剩下的n-2个数据的算术平均值;若n为1或2,则为普通的算术平均值。
输入 输入数据有多行,每一行上有若干个实数,对应一种情形(数据之间用一个空格字符分隔)。
输出 对于每一种情形,依次输出数据的个数、最小值、最大值、平均值、换行。其中数据之间用逗号和空格分隔,浮点型数据保留2位小数。
输入样例
1
1 1
-1 -2 -1.2
输出样例
1, 1.00, 1.00, 1.00
2, 1.00, 1.00, 1.00
3, -2.00, -1.00, -1.20
#include <stdio.h>
int GetData(double *array);
// 读取数据从p指定的地址处开始存放,返回读取的数据个数
void Aver(const double *array, int n, double *min, double *max, double *aver);
// 接收数组三要素(数据类型、起始地址、元素个数),计算并间接"返回"数组的最小值、最大值、"平均值"
int main()
{
double array[1024], aver, min, max;
int n;
while( (n=GetData(array)) > 0 )
{
Aver(array, n, &min, &max, &aver);
printf("%d, %.2lf, %.2lf, %.2lf\n", n, min, max, aver);
}
return 0;
}
int GetData(double *array) // 接收一系列double型数据,存放到array为首地址的数组中,返回接收到的数据项数
{ // 隐含假定array为首地址的数组要事先准备好,并且有足够的容量
int n, flag=1;
char c;
for(n=0; flag && scanf("%lf%c", array+n, &c)==2; n++)
{ // 注意此处"%d%c"中间不要插入空格
if(c=='\n') flag = 0;
} // 注意此处不要用break,否则少执行一次for循环的表达式3(n++)
return n;
}
void Aver(const double *array, int n, double *min, double *max, double *aver)
{ // 通过指针型参数间接"返回"多个值(最小、最大、均值)
int i;
*min = *max = *aver = array[0];
for(i=1; i<n; i++)
{
if(array[i]<*min) *min = array[i];
if(array[i]>*max) *max = array[i];
*aver += array[i];
}
if(n<=2)
*aver /= n;
else
*aver = (*aver - *min - *max)/(n-2);
}
4 字符串倒置
问题描述 对于给定的字符串,将其按字符倒置。
输入 输入数据有多行。每一行为一个字符串(字符串长度小于1024,其中可能含有空格字符),对应一种情形。
输出 对于每一种情形,输出结果并换行。
输入样例
Abc
abc def
1230
输出样例
cbA
fed cba
0321
#include <stdio.h>
char *reverse(char *str)
{
char temp;
int left, right;
for(right=0; str[right]!='\0'; right++)
;
if(right>0) right--;
for(left=0; left<right; left++,right--)
{
temp = str[left];
str[left] = str[right];
str[right] = temp;
}
return str;
}
#define N 1024
int main()
{
char str[N];
while(gets(str))
printf("%s\n", reverse(str));
return 0;
}
5 字符在字符串中首次出现的位置
问题描述 给定一个字符、一个字符串(字符串的长度小于1024),计算该字符在字符串中首次出现的位置。
输入 输入数据有若干行。每两行对应一种情形,这两行中的第一行上有一个字符(请注意将该字符后面的换行字符“吃掉”),第二行上有一个字符串(字符串中可能含有空白字符)。
输出 对于每一种情形,输出计算结果(若字符不在字符串中,则输出0),然后换行。
输入样例
a
abcd
a
baaa
a
xyz
输出样例
1
2
0
#include <stdio.h>
int Pos(char c, const char *str)
{
int i;
for(i=0; str[i]!='\0'; i++)
if(str[i]==c)
return i+1;
return 0;
}
#define N 1024
int main()
{
char ch, str[N];
while(scanf("%c", &ch)==1) // 仅读取字符,其后的换行字符待处理
{
gets(str); // 读取字符所在行的换行字符'\n'(此时读取的字符串长度为0)
gets(str); // 本语句读取的为待处理字符串
printf("%d\n", Pos(ch, str));
}
return 0;
}
6 折纸的厚度
问题描述 假定有一张充分大的纸,并且可以进行许多次对折。若单张纸的厚度为x,计算经过多少次对折后,折纸的厚度超过珠穆朗玛峰的高度8844.43米(8844430毫米)。
输入 输入数据仅有一行。该行有若干个数据分别表示单纸张的厚度(以毫米为单位),对应每一种情形。
输出 对于每一种情形,直接输出结果,换行。
输入样例
0.1 0.3 0.5
输出样例
27
25
25
【提示】请注意毫米与米的单位换算。
#include<stdio.h>
int main()
{
double thickn;
int i=0;
while(scanf("%lf",&thickn)==1)
{
//scanf("%lf",&thickn);
while(1)
{
if(thickn>8844430.0)
{
printf("%d\n",i);
i=0;
break;
}
thickn=thickn*2.0;
i++;
}
}
return 0;
}
7 计算和式
问题描述 给定两个正整数a(1≤a≤9)和n(n≥1),计算[a]+[aa]+…+[a…a]的值。例如:a为2,n为5时,则计算2+22+222+2222+22222。
输入 输入数据有若干行。每行有两个整数,分别是a和n,对应每一种情形。
输出 对于每一种情形,直接输出计算结果、换行。
输入样例
2 5
3 6
1 4
输出样例
24690
370368
1234
#include<stdio.h>
int main()
{
int a,n,i,sum=0,b;
while(scanf("%d%d",&a,&n)==2)
{
b = a;
for(i=0;i<n;i++)
{
sum+=b;
b = 10 * b + a;
}
printf("%d\n",sum);
sum = 0;
}
return 0;
}
8 乘方计算
问题描述 给定一个unsigned long long型数据
x
x
x,计算
x
2
,
x
3
,
⋯
x^2, x^3,\cdots
x2,x3,⋯直到
x
5
x^5
x5或溢出为止。
输入 输入数据有若干行。每行上有一个unsigned long long型整数,对应一种情形。
输出 对于每一种情形,依次输出
x
,
x
2
,
x
3
,
x
4
,
x
5
x, x^2, x^3, x^4, x^5
x,x2,x3,x4,x5的值,不输出计算溢出的数值。数据项之间用逗号、空格分隔。
输入样例
1111
11111
111111
输出样例
1111, 1234321, 1371330631, 1523548331041, 1692662195786551
11111, 123454321, 1371700960631, 15240969373571041
111111, 12345654321, 1371737997260631
【提示】在头文件climits(或limits.h)中宏定义了一些名称,用以表示一些数据类型取值的最大值。但不同的编译系统中宏定义的标识符为不尽一致。例如:有的用ULONG_LONG_MAX,而有的用ULLONG_MAX。可以采用如下办法在程序中统一使用ULONG_LONG_MAX。
#include <limits.h>
#ifndef LONG_LONG_MAX
#define LONG_LONG_MAX LLONG_MAX
#define ULONG_LONG_MAX ULLONG_MAX
#endif
#include<stdio.h>
#include<math.h>
#include<limits.h>
#ifndef LONG_LONG_MAX
#define LONG_LONG_MAX LLONG_MAX
#define ULONG_LONG_MAX ULLONG_MAX
#endif
int main()
{
unsigned long long n,a=1,i;
while(scanf("%llu",&n)==1)
{
printf("%llu", n);
for (i = 2; i <= 5;i++)
{
a = pow(n, i);
printf(", %llu", a);
if(a>(ULONG_LONG_MAX / n))
break;
}
printf("\n");
}
return 0;
}
9 将非负十进制整数各位倒置
问题描述 给定一个非负整数,将其按十进制各位倒置。
输入 输入数据有若干行。每行上有一个非负整数,对应一种情形。
输出 对于每一种情形,直接输出结果,换行。
输入样例
123450
6
0
输出样例
54321
6
0
#include<stdio.h>
#include<math.h>
int main()
{
int a,a1,length,sum,i;
while(scanf("%d",&a)==1)
{
sum=0;
length = log10(a)+1;//取位数
a1=a;
/*for(length=1;;length++)//求位数
{
a1=a1/10;
if(a1==0)
break;
}*/
/*while(a1!=0)
{
a1 = a1 / 10;
length++;//取位数
}*/
for(i=length-1;i>=0;i--)
{
sum=sum+a%10*pow(10,i);
a=a/10;
}
printf("%d\n",sum);
}
return 0;
}
10 判断同构数
问题描述 给定一个十进制正整数,判断其是否为同构数。所谓同构数是这样的一些数,它出现在其平方数的右边,例如5是出现在
5
2
=
25
5^2=25
52=25右边的数,25是出现在
2
5
2
=
625
25^2=625
252=625右边的数,所以5和25都是同构数。
输入 输入数据有若干行。每行上有一个正整数,对应一种情形。
输出 对于每一种情形,输出Y(表示是同构数)或N(表示不是同构数),换行。
输入样例
5
15
25
输出样例
Y
N
Y
#include<stdio.h>
#include<math.h>
int main()
{
int length=0, a, a1,b,c;
while(scanf("%d",&a)==1)
{
length = 0;
b = a * a;
a1 = a;
while(a!=0)
{
a = a / 10;
length++;//取位数
}
c = pow(10, length);
if(a1==b%c)
printf("Y\n");
else
printf("N\n");
}
return 0;
}
11 兑换钱币
问题描述 对于给定的人民币金额n(分),问有多少种方案将其兑换成1分、2分、5分。
输入 输入数据有若干行。每行上有一个正整数表示以分为单位的人民币金额n,对应一种情形。
输出 对于每一种情形,输出结果、换行。
输入样例
10
100
150
输出样例
10
541
1186
#include<stdio.h>
int main()
{
int a1=0, a2=0, a5=0,n,flag=0;
while(scanf("%d", &n)==1)
{
flag = 0;
for (a5 = 0; a5 <= n/5; a5++)
{
a2 = (n - 5 * a5) / 2 + 1;
flag += a2;
}
printf("%d\n", flag);
}
return 0;
}
12 给定5个实数的算术平均值和几何平均值
问题描述 给定5个实数,计算其算术平均值及几何平均值。
输入 输入数据仅有若干行,每行上有5个双精度浮点型数据,对应一种情形。
输出 对于每一种情形,输出算术平均值、逗号、空格、几何平均值、换行(浮点数保留2位小数)。
输入样例
1.5 2.0 6.2 4.3 5
1 -2 3 -4 5
输出样例
3.80, 3.31
0.60, 2.61
#include<stdio.h>
#include<math.h>
int getdata(double *a);
int main()
{
double a, n[10],sum1,sum2,a1,a2;
int i;
while((a=getdata(n))>0)
{
sum1 = 0;
sum2 = 1;
for (i = 0; i < 5; i++)
{
sum1 += n[i];
sum2 *= n[i];
}
a1 = sum1 / 5;
if (sum2 < 0)
a2 = -pow(-sum2, 0.2);
else
a2 = pow(sum2, 0.2);
printf("%.2lf, %.2lf\n", a1, a2);
}
}
int getdata(double *n)
{
int a, flag=1;
char c;
for(a=0; flag && scanf("%lf%c", n+a, &c)==2; a++)
{
if(c=='\n') flag = 0;
}
return a;
}
13 指示灯控制
问题描述 有m(m<100)盏灯排成一排(从1到m按顺序依次编号)。灯的开关均为点触式的(即点一次开、再点一次则关)。现有n个人(从1到n依次编号)。第一个人(1号)将灯全部关闭。第二个人(2号)将所有2的倍数编号的灯的开关点一下。第三个人(3号)将所有3的倍数编号的灯的开关点一下。依此类推,当n个人完成其操作后,计算灯亮的数目。
输入 输入数据有若干行。每行上有两个非负整数对应一种情形的m和n。
输出 对于每一种情形,输出计算结果、换行。
输入样例
7 7
3 4
6 4
输出样例
5
2
2
#include<stdio.h>
int main()
{
int a[100];
int n,m,i,j,flag;
while(scanf("%d %d",&m,&n)==2)
{
flag = 0;
for (i = 0; i < m;i++)
{
a[i] = 1;
}
for (i = 0; i < n;i++)
{
for (j = i;j<m;j=j+i+1)
{
a[j] = -a[j];
//7printf("%d", a[j]);
}
}
for (i = 0; i < m;i++)
{
if(a[i]==1)
flag++;
}
printf("%d\n", flag);
}
return 0;
}
14 分类统计字符串中各类字符的个数
问题描述 给定一个字符串,统计其中空格、数码、大写字母、小写字母的个数。
输入 输入数据有若干行。每一行上有一个字符串(长度小于1024字符),对应一种情形。
输出 对于每一种情形,依次输出空格的个数、数码字符的个数、大写字母的个数、小写字母的个数,数据之间用逗号及空格字符分隔,然后换行。
输入样例
cout << “OK.” << endl;
C/C++, Java, Python, HTML5
输出样例
4, 0, 2, 8
3, 1, 8, 8
#include<stdio.h>
int main()
{
char str[1024];
int n,blank=0,num=0,letter=0,LETTER=0;
while(gets(str))
{
blank = 0, num = 0, letter = 0, LETTER = 0;
n = strlen(str);
//printf("%d",n);
for (int i = 0; i < n;i++)
{
if(str[i]>='A'&&str[i]<='Z')
LETTER++;
else if(str[i]>='a'&&str[i]<='z')
letter++;
else if(str[i]==' ')
blank++;
else if(str[i]>='0'&&str[i]<='9')
num++;
}
printf("%d,%d, %d, %d\n", blank, num, LETTER, letter);
}
return 0;
}
15 态度决定一切
问题描述 将英文26个字母AZ,或az对应到整数1~26,则态度 Attitude 对应的数字之和为100。编程计算给定的字符串对应的数字之和(规定非英文字母的字符均对应0)。
输入 输入数据有多行,每行上有一个字符串(长度小于1024)对应一种情形。
输出 对于每一种情况,输出结果、换行。
输入样例
attitude
Hard Work
knowledge
输出样例
100
98
96
#include<stdio.h>
int main()
{
char str[1024];
int i,n,sum1,sum2;
while(gets(str))
{
sum1 = 0, sum2 = 0;
n = strlen(str);
for (i = 0; i < n; i++)
{
if (str[i] >= 'A' && str[i] <= 'Z')
sum1 += str[i] - 'A'+1;
else if (str[i] >= 'a' && str[i] <= 'z')
sum2 += str[i] - 'a'+1;
}
printf("%d", sum1 + sum2);
}
return 0;
}