山东科技大学OJ部分题目记答案副本.docx
《山东科技大学OJ部分题目记答案副本.docx》由会员分享,可在线阅读,更多相关《山东科技大学OJ部分题目记答案副本.docx(101页珍藏版)》请在冰豆网上搜索。
山东科技大学OJ部分题目记答案副本
C语言精彩作图之一颗三维的心
/*Heart*/
#include
#include
#definePI3.
voidmain()
{
doublea;
intx,y,y1,r,r1;
intgdriver=DETECT,gmode;
initgraph(&gdriver,&gmode,"c:
\\tc");
printf("PleaseinputRadus(<80):
");
scanf("%d",&r);
cleardevice();
setbkcolor(9);
setcolor(4);
outtextxy(80,20,"ThisprogramshowtheHeartpicture.");
y1=240-r;
for(a=0;a<=2*PI;a+=PI/27)
{x=320+r*cos(a);
y=240+r*sin(a);
r1=sqrt((x-320)*(x-320)+(y-y1)*(y-y1));
circle(x,y,r1);
}
outtextxy(80,460,"Pressanykeytoquit...");
getch();
closegraph();
}
用C语言显示BMP图形
#include"stdio.h"
#include"dir.h"
#include"dos.h"
#include"graphics.h"
char*malloc();/*malloc转换*/
charbmp_to_dat(char*bmp,char*dat)
/*将16色BMP文件转换为可以用putimage输出的格式,bmp为原BMP文件,dat为转化文件*/
{
unsignedcharc[8],scan_times,scan_pixs;
unsignedcharworkpos;inti,j,k,n,nowpos,iw,ih;
staticintcolor[16]={0,4,2,6,1,5,3,7,8,12,10,14,9,13,11,15};
unsignedcharworkline[640],scanline[640];
FILE*fp,*targetfp;
union
{
unsignedcharvalue;
struct
{
unsignedcl:
4;
unsignedch:
4;
}color;
}mycolor;
if((fp=fopen(bmp,"rb"))==NULL)return(0);
targetfp=fopen(dat,"wb");
fseek(fp,18,SEEK_SET);
iw=0;ih=0;
fread(&iw,4,1,fp);/*读图像宽度*/
fread(&ih,4,1,fp);/*读图像高度*/
if(iw==0&&ih==0&&iw>640&&ih>480)
{fclose(fp);fclose(targetfp);return(0);}
iw--;ih--;/*∵putimage中的长宽比实际数值少1*/
scan_times=iw/8+1;/*行处理单位数*/
scan_pixs=scan_times*4;/*行像素字节数∵1单位=4字节*/
fputc(iw%256,targetfp);/*填充信息头:
长、宽部分*/
fputc(iw/256,targetfp);
fputc(ih%256,targetfp);
fputc(ih/256,targetfp);
fseek(fp,-scan_pixs,SEEK_END);
for(j=0;j<=ih;j++)
{nowpos=0;
fread(scanline,scan_pixs,1,fp);
fseek(fp,-scan_pixs*2,SEEK_CUR);
for(n=3;n>=0;n--)/*解码4个位面*/
{for(i=0;i{workpos=0;
for(k=0;k<4;k++)/*分离出8个像素*/
{mycolor.value=scanline[i*4+k];
c[k*2]=color[mycolor.color.ch];
c[k*2+1]=color[mycolor.color.cl];
}
for(k=0;k<8;k++)workpos+=(c[k]>>n&1)<<(7-k);
workline[nowpos]=workpos;nowpos++;
}}
fwrite(workline,scan_pixs,1,targetfp);
}
fclose(fp);fclose(targetfp);
return
(1);
}
main()
{
intgd=VGA,gm=VGAHI,n;
char*buffer,bmpfile[13],_16file[13]={0};
FILE*fp;
structffblk*ff;
/*registerbgidriver(EGAVGA_driver);*/
initgraph(&gd,&gm,"C:
\\tc");
printf("Nowstarttodisplay16colorbmp.\n\n");
puts("Pleasechoice:
");
printf("0.Quit\n1.BMPfilename\n");
while
(1)
{
n=getch();
switch(n)
{
case0:
continue;
case'0':
exit(0);
case'1':
{
printf("PleaseinputBMPfilename(*.bmp):
");
gets(bmpfile);
gotoOUT;
}OUT:
strncpy(_16file,bmpfile,strlen(bmpfile)-3);
strcat(_16file,"dat");
if(!
bmp_to_dat(bmpfile,_16file))
{
puts("Can'topenfile!
");
closegraph();
exit(0);
}
fp=fopen(_16file,"rb");
findfirst(_16file,ff,FA_ARCH);
if((buffer=malloc(ff->ff_fsize))==NULL)exit(0);
n=0;
while(!
feof(fp))
{
buffer[n]=fgetc(fp);
n++;
}
for(n=0;n<100;n++)
{
putimage(350-n,n/2,buffer,COPY_PUT);
}
getch();
closegraph();
free(buffer);
fclose(fp);
}
ProblemA:
简单的打折计算
Description
商店规定:
消费满n元,可以打八八折。
设某件商品标价m元,输入购买的件数x,计算出需要支付的金额(单位:
元),精确到分。
Input
输入只有一行,三个整数m、n和x,且0Output
输出金额,精确到分。
SampleInput
953004
SampleOutput
334.40
HINT
了解浮点型的输出控制,注意整型和浮点型混合运算过程中的数据类型转换。
#include
intmain()
{intm,n,x;
floats;
scanf("%d%d%d",&m,&n,&x);
if(m*x>=n)
s=m*x*0.88;
else
s=m*x;
printf("%.2f",s);
}
ProblemB:
判断闰年
Description
输入一个正整数的年份,判断是否为闰年。
Input
输入只有一行,为一个10000以内的正整数。
Output
输出为一行。
若输入为闰年偶数则输出“Yes”,否则输出“No”。
SampleInput
2010
SampleOutput
No
HINT
了解逻辑运算符和关系运算符。
#include
intmain()
{
inty;
scanf("%d",&y);
if(y%4==0&&y%100!
=0||y%400==0)
printf("Yes");
else
printf("No");
}
ProblemC:
水仙花数
Description
如果一个三位十进制数等于其各位数字的立方和,则称这个数为水仙花数。
如:
13+53+33=153。
Input
一个整数x,100<=x<=999。
Output
x是水仙花数,则输出“YES”,否则为“NO”。
SampleInput
153
SampleOutput
YES
HINT
#include
intmain()
{
intx,a,b,c;
scanf("%d",&x);
a=x%10;
b=x/10%10;
c=x/100;
if(a*a*a+b*b*b+c*c*c==x)
printf("YES");
else
printf("NO");
}
ProblemA:
多少张钞票
Description
客户去商店买东西时,不超过100美金的账单喜欢用现金支付。
商店喜欢用最少的钞票给付客户的找零。
请你编写一个程序帮助商店计算出:
当客户买了x元商品给了一张100美元的钞票后,商店应该付给客户多少张20美元、10美元、5美元和1美元的钞票,使得钞票总数最少。
假设不存在其他面值的钞票,也不会有几角几分的价格,商店的各种钞票总是够用的。
Input
输入一个整数x,0Output
按顺序输出20美金、10美金、5美金和1美金面值的钞票张数。
输出格式见sample。
SampleInput
7
SampleOutput
$20bills:
4
$10bills:
1
$5bills:
0
$1bills:
3
HINT
当能支付大面值钞票时不要支付更小面值的钞票,才能满足钞票总数最少,注意scanf()格式的控制。
#include
intmain()
{intx,s,a,b,c,d;
scanf("%d",&x);
s=100-x;
a=s/20;
b=(s-20*a)/10;
c=(s-20*a-10*b)/5;
d=s-20*a-10*b-c*5;
printf("$20bills:
%d\n",a);
printf("$10bills:
%d\n",b);
printf("$5bills:
%d\n",c);
printf("$1bills:
%d\n",d);
}
ProblemB:
自动拨出电话的程序
Description
某外国销售公司需要向国内的一些大型单位打电话推销产品。
这个公司的工作场景是这样推销员坐在自己电脑旁边,通过一款自动拨电话的软件与客户联系。
所有需要被拨打的电话号码都事先存储在服务器上,推销员不需要每次都很麻烦的输入客户的电话号码,当推销员点击软件里拨打的按钮,下一个电话将会自动拨出。
现在你需要编写个程序来模拟这个自动拨电话软件的工作过程。
电话号码是按照中国的习惯存储下来的,可能是从网站上抓取的,也可能是扫描的手写件。
不过它们都被按照这样的格式存储下来:
(城市区号)分区前缀-分机号
比如青岛的一个大型单位的某部电话是(0532)621-15486,是指如果在单位内部直接拨打15486就行,在青岛的其他地方要拨打,而在北京要拨打6。
根据常识,先拨0就是要转外线,所以一般电话号码的各个部分都不会以0开头。
你的程序可以把如上格式的电话号码翻译成一个只包含有数字的串,发送给电话机并拨出。
值得注意的是中国的城市区号长度并不相同,比如北京是010。
再有不同城市的电话号码位数也不相同,并且不同单位根据内部电话分机数目多少,有的可能只有3位分机号码,有的可能分区前缀号会只有2位。
但不管怎样中国现在还没有哪个城市的电话号码超过十位数的。
中国的国际区号是0086。
这里不含像114这样的特服电话。
Input
输入只有一行,是符合“(城市区号)分区前缀-分机号”规律的电话号码,这里面除了英文字符“(”、“)”、“-”之外只有数字。
Output
输出只有一行,是带中国区号的能电话号码。
注意从国外打国内的电话,城市区号前面的0是不用拨打的。
比如中国青岛的国际分区号是。
SampleInput
(0532)621-15486
SampleOutput
5486
HINT
这是个可以用scanf()解决的问题,请注意电话号码都是数字这个规律。
#include
intmain()
{
inta,b,c;
scanf("(0%d)%d-%d",&a,&b,&c);
printf("0086%d%d%d",a,b,c);
}
ProblemC:
求1+2+...+n=?
Description
给定一个n,求出s=1+2+3+...+n的值。
Input
输入只有一行,包含一个正整数n(n<=232)。
Output
输出一行,为1+2+...+n的值。
SampleInput
10
SampleOutput
55
HINT
n的数据范围大,需注意数据类型的选择和计算次序,以避免数据溢出。
#include
intmain()
{
unsignedlonglongintn,s,i;
scanf("%llu",&n);
if(n%2==0)
s=n/2*(n+1);
else
s=(n+1)/2*n;
printf("%llu",s);
}
ProblemD:
2的多少次幂
Description
从键盘输入一个数x,x是2的整数次幂(x=2y),请编程求出y的值。
Input
一个非负有理数x,x在[0,2256]范围内。
Output
一个整数y。
SampleInput
1
SampleOutput
0
HINT
看起来数据很大,但是用double完全可以存储。
为什么?
请研究下IEEE-754标准的浮点数存储格式。
这里要用到C语言标准库的数学函数。
#include
#include
intmain()
{doublex,n;
scanf("%lf",&x);
n=(log10(x))/(log10
(2));
printf("%d",(int)n);
}
ProblemE:
三个数比较大小
Description
从键盘上输入0~100之间的三个数,按从小到大的顺序输出。
Input
输入只有一行,为三个整数。
Output
按从小到大输出这三个数。
SampleInput
151020
SampleOutput
101520
HINT
用if语句判断各种情况可以解决这个问题。
#include
intmain()
{
intx,y,z,a;
scanf("%d%d%d",&x,&y,&z);
if(x>y)
{
a=x;
x=y;
y=a;
}
if(x>z)
{
a=x;
x=z;
z=a;
}
if(y>z)
{
a=y;
y=z;
z=a;
}
printf("%d%d%d",x,y,z);
}
ProblemA:
输出是m的倍数或n的倍数、但不是m和n的公倍数的数
Description
输出1~k之间是m的倍数或n的倍数、但不是m和n的公倍数的数,其中1<=m,nInput
输入三个整数,依次为k、m、n。
Output
从小到大输出符合题意的所有整数,两数之间用一个空格分开。
SampleInput
1523
SampleOutput
23489101415
HINT
难点在于输出格式的控制:
空格在数的中间,学会用循环时边界情况的特殊处理。
#include
intmain()
{
intk,m,n,i=0,j;
scanf("%d%d%d",&k,&m,&n);
for(j=1;j<=k;j++)
{
if((j%m==0&&j%n!
=0)||(j%m!
=0&&j%n==0))
{i++;
if(i==1)
printf("%d",j);
else
printf("%d",j);}
}
}
ProblemB:
n个数的最大值和最小值
Description
找出n个数中最大的数和最小的数,并将它们的值输出出来。
Input
输入为n+1个整数,都在int类型范围内。
这些数可能用若干空格或者换行符分隔开。
输入的第1个数为n,表示后续有n个数输入。
从输入的第2个数开始,求出直到第n+1个数中最大的数和最小的数。
Output
输出为两行,格式见sample。
SampleInput
301-1
SampleOutput
Themaximumnumberis1.
Theminimumnumberis-1.
HINT
分隔符是空格还是回车都是空白符,对scanf("%d")来说没有区别;先读入n,然后用for循环就很容易控制读入n个数的过程。
#include
intmain()
{
inti,n,m,max,min;
scanf("%d%d",&n,&max);
min=max;
for(i=1;i{scanf("%d",&m);
if(m>max)
max=m;
if(mmin=m;}
printf("Themaximumnumberis%d.\nTheminimumnumberis%d.",max,min);
}
ProblemC:
成绩的等级
Description
把百分制的考试成绩转换成五级制的成绩:
90~100:
Excellent
80~89:
Good
70~79:
Average
60~69:
Pass
0~59:
Failing
不在0~100之间的输入是非法数据,输出“Error”。
Input
输入多行,每行一个整数。
Output
输入所对应的成绩等级。
SampleInput
-1
81
92
35
68
72
100
SampleOutput
Error
Good
Excellent
Failing
Pass
Average
Excellent
HINT
用switch语句解决这个问题比较方便。
#include
#include
#include"string.h"
intmain()
{
intn;
while(scanf("%d",&n)!
=EOF)
{
if(n==100)
printf("Excellent\n");
elseif(n<0||n>100)
printf("Error\n");
else
switch(n/10)
{case9:
printf("Excellent\n");break;
case8:
printf("Good\n");break;
case7:
printf("Average\n");break;
case6:
printf("Pass\n");break;
default:
printf("Failing\n");
}
}
return0;
}
ProblemD:
A+BProblem
Description
计算a+b,0<=a,b<1000。
Input
输入有多对整数a和b组成,每对a和b占一行,a,b用空格分开。
Output
每行输出一个a+b的值,顺序与输入对应。
SampleInput
12
1020
SampleOutput
3
30
HINT
OJ系统上测试输入结束符为EOF(EndOfFile),其值为-1。
用scanf()把文件所有内容读完后,会读到EOF,所以可以用来判断输入是否完成,测试时可以用Ctrl+Z产生EOF。
本题解法参看FAQ。
AppendCode
#include
intmain()
{inta,b;
while(scanf("%d%d",&a,&b)!
=EOF)
{
printf("%d\n",a+b);
}
return0;
}
ProblemE:
A+BProblem(II):
Input/OutputPratice
Description
计算a+b,0<=a,b<1000。
Input
输入的第一行是一个整数N,后面有N对整数a和b,每对a和b占一行,a,b用空格分开。
Output
每行输出一个a+b的和,顺序与输入对应。
SampleInput
2
12
1020
SampleOutput
3
30
HINT
N给出了测试样例数,用for循环处理方便。
#include
intmain()
{
intN,i,j;
scanf("%d",&N);
inta[N][2];
for(i=0;i{
for(j=0;j<2;j++)
scanf("%d",&a[i][j]);
}
for(i=0;iprintf("%d\n",a[i][0]+a[i][1]);
}
ProblemA:
A+BProblem(III):
Input/OutputPratice
Des