【XDOJ】C语言期末真题带练(2020)

【XDOJ】C语言期末真题带练(2020)

矩阵类题目

矩阵复制

输入矩阵A,并输入两个整数m和n,对矩阵A进行m×n块复制,生成新的矩阵并输出,该过程示意图如下:
1

#include <stdio.h>

int main()
{
	int a,b,i,j;
	scanf("%d %d",&a,&b);
	int c[10][10];
	for(i=0;i<a;i++)
	{
		for(j=0;j<b;j++)
		{
			scanf("%d",&c[i][j]);
		}
	}
	int m,n;
	scanf("%d %d",&m,&n);
	for(i=a;i<a*m;i++)
	{
		for(j=0;j<b;j++)
		{
			c[i][j]=c[i-a][j];
		}
	}//复制行
	for(j=b;j<b*n;j++)
	{
		for(i=0;i<a*m;i++)
		{
			c[i][j]=c[i][j-b];
		}
	}//复制列
	for(i=0;i<a*m;i++)
	{
		for(j=0;j<b*n;j++)
		{
			printf("%d",c[i][j]);
		}
		printf("\n");
	}
}

方阵旋转

输入维度为m(m为正偶数)的方阵,将其沿中心点所在的水平线和垂直线平均分成4块,每块都是(m/2)*(m/2)的方阵,然后将其沿中心点进行分块顺时针90度旋转后输出。

#include <stdio.h>

int main()
{
	int m,i,j;
	scanf("%d",&m);
	int a[10][10],b[10][10];
	for(i=0;i<m;i++)
	{
		for(j=0;j<m;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	for(i=0;i<m/2;i++)
	{
		for(j=0;j<m/2;j++)
		{
			b[i][j]=a[i+m/2][j];
		}
	}//左下到左上 
	for(i=m/2;i<m;i++)
	{
		for(j=0;j<m/2;j++)
		{
			b[i][j]=a[i][j+m/2];
		}
	}//右下到左下 
	for(i=0;i<m/2;i++)
	{
		for(j=m/2;j<m;j++)
		{
			b[i][j]=a[i][j-m/2];
		}
	}//左上到右上 
	for(i=m/2;i<m;i++)
	{
		for(j=m/2;j<m;j++)
		{
			b[i][j]=a[i-m/2][j];
		}
	}//右上到右下 
	for(i=0;i<m;i++)
	{
		for(j=0;j<m;j++)
		{
			printf("%d ",b[i][j]);
		}
		printf("\n"); 
	}
}

三角形探测

输入m行3列的整数矩阵,若将每行的3个数据作为三角形的三条边长,判断其是否能构成三角形,如果可以,计算该三角形面积的平方并取整(向上取整),并按照从大到小的顺序输出此取整后的面积平方及该三角形所在的行号(行号从0开始计数),如面积取整后相等,则行数小的优先输出。如无满足条件的行,输出no。
(注:三边长为a,b,c的三角形的面积平方等于p*(p-a)(p-b)(p-c),其中p为周长的一半)

#include <stdio.h>

int main()
{
	int m,i,j,count=0,q;
	scanf("%d",&m);
	int flag=0;
	float p;
	int a[30][3],s[i],n[i];
	for(i=0;i<m;i++)
	{
		for(j=0;j<3;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	for(i=0;i<m;i++)
	{
			if(a[i][0]+a[i][1]>a[i][2]&&a[i][0]+a[i][2]>a[i][1]&&a[i][2]+a[i][1]>a[i][0])
			{
				flag=1;
				p=(float)(a[i][0]+a[i][1]+a[i][2])/2;//此处p为小数 
				s[count]=p*(p-a[i][0])*(p-a[i][1])*(p-a[i][2]);
				n[count]=i;//记录面积及位置 
				count++;
			}
	}
	for(i=0;i<count-1;i++)
	{
			for(j=0;j<count-1-i;j++)
			{
				int t;
				t=s[j];
				s[j]=s[j+1];
				s[j+1]=t;
				t=n[j];
				n[j]=n[j+1];
				n[j+1]=t;
			}
	}//注意排序后面积和位置的角标都要改变 
	if(flag)
	{
		for(i=0;i<count;i++)
		{
			printf("%d %d",s[i],n[i]);
			printf("\n");
		}
	}
	else
	printf("no");
}

综合类题目(结构体)

软件工程重点实验室有研究生45人,每天第一个到实验室的人要把门打开,最后一个离开的人要把门关好。现有一堆杂乱的实验室签到、签离记录,请根据记录找出当天开门和关门的人。(没有同时签到或同时签离)

#include <stdio.h>

char change(char a[])//函数类型和传参变量类型要一致 
{
	int h,m,s,t;
	h=10*(a[0]-'0')+a[1]-'0';
	m=10*(a[3]-'0')+a[4]-'0';
	s=10*(a[6]-'0')+a[7]-'0';
	t=3600*h+60*m+s;
	return t;
}//将字符串转换为时间 
struct student
{
	char a[100];
	char b[10];
	char c[10];
};
int main()
{
	int n,i,t1,t2,max,min,MIN,MAX;
	scanf("%d",&n);
	struct student per[n];
	for(i=0;i<n;i++)
	{
		scanf("%s%s%s",per[i].a,per[i].b,per[i].c); 
	}//接收信息 
	min=change(per[0].b);
	max=change(per[0].c);
	for(i=0;i<n;i++)
	{
		if(change(per[i].b)<min)
		{
			min=change(per[i].b);
			MIN=i;
		}
		if(change(per[i].b)>min)
		{
			max=change(per[i].b);
			MAX=i;
		}
	}//找到最早到的和最晚到的 
	printf("%s %s",per[MIN].a,per[MAX].a);
}

人口普查

某城镇进行人口普查,得到了全镇居民的生日。请编写程序,找出镇上最年长和最年轻的人。(这里假设镇上没有超过200岁的老人,假设今天是2021年1月9日,所以超过200岁的生日和未出生的生日都是不合理的,应该被过滤掉)

#include<stdio.h>
#include<string.h>
int main()
{
	char name[1000][10];
	int year[1000],month[1000],day[1000];
	int n,i;
	int sum[1000],longest,youngest;
	
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%s",name[i]);
		scanf("%d/%d/%d",&year[i],&month[i],&day[i]);
	}//输入信息
	int judge1=1821*365+30+9;
	int judge2=2021*365+30+9; 
	for(i=0;i<n;i++)
	{
		sum[i]=year[i]*365+month[i]*30+day[i];
		if(sum[i]>judge2||sum[i]<judge1)
		{
			sum[i]=0;
		}//过滤掉不符合实际的年龄
	}
	int min=sum[0];
	int max=sum[0];
	int result=0;
	for(i=0;i<n;i++)
	{
		if(sum[i]!=0)
		{
			result++;
			if(sum[i]<=min)
			{
				min=sum[i];
				youngest=i;
			}
			if(sum[i]>=max)
			{
				max=sum[i];
				longest=i;
			} 
		}
	}
	if(result!=0)
	{
		printf("%d\n",result);
		printf("%s\n%s",name[youngest],name[longest]);
	}
	if(result==0)
	{
		printf("%d",result);
	}
	return 0;
}
  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值