原文:
欢迎大家继续留在蓝点工作室,希望大家可以在蓝点这个大家庭里面学到更多的专业技能知识,回报总是和努力成正比的。以下十道题是大二的学长学姐出的,大家在过程中有什么问题可以在群里讨论或者私聊我们。大家基本都做了科技月月评,以下题目对大家来说都不是问题,主要是巩固大家的知识,大家平时学习一定要多动实践,这样才能把所学的知识融会贯通,不然学了过段时间又会忘记。
作业期限两个星期。做完交给对应的负责人即可。
祝大家冬至快乐哟,吃饺子去了,哈哈。
一、在X星系的广袤空间中漂浮着许多X星人造“炸弹”,用来作为宇宙中的路标。
每个炸弹都可以设定多少天之后爆炸。比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16日爆炸。 有一个贝塔炸弹,2014年11月9日放置,定时为1000天,请你计算它爆炸的准确日期。
二、请定义一个描述学生基本信息的结构,包括姓名,学号,籍贯,身份证号,年龄,家庭 住址,性别,联系方式等。并定义一个结构体数组。编程: a) 编写函数 input() , 输入基本信息(3~5 条记录); b) 编写函数 print(),输出全体记录信息; c) 编写函数 search(), 检索一个指定的学生信息并返回, 由主函数打印到屏幕上; d) 说明,访问结构的时候,什么时候应该用运算符“.”,什么时候应该用运算符“->”。
三、 可变参数
C 语言允许定义一个函数,能根据具体的需求接受可变数量的参数。
例如:
int fun(int, … )
{ … }
int main()
{
fun(1, 2, 3);
fun(1, 2, 3, 4);
}
一个可变参数的函数里有如下标识(函数):
<T> fun(<T> i, … )
{
…
va_list p;
// p 是一个字符指针, va_list 就是 char*
…
va_start(p, i);
// 这个函数将 p 指向 i 所在的地址
…
va_end(p);
// 结束的标志, p 将指向 0 地址
…
return <T>;
// T 可以是任何基本数据类型,
// void 时,第一个 T 为 void,第二个为除 void 外的其他数据类型
// 最后是 return; 表示没有返回值,并结束程序运行。
}
要求:
按可变参数函数的标准写一个 sum 函数,按一下方式调用 sum 方法:
sum(12, 23, 54, 76, END);
sum(12, 34, 657, 54, 23, 54, END);
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, END);
// END 为自己规定的结束标识
或是这种方式:
sum(4, 12, 23, 54, 76);
sum(6, 12, 34, 657, 54, 23, 54);
sum(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// sum 里的第一个参数是参与加法元素的个数
分别返回:
165
834
55
四、最大子数组和
问题描述
一个整数数组中的元素有正有负,在该数组中找出一个连续子数组,要求该子数组中各元素的和最大,这个子数组便被称作最大子数组。( 至少要用二种算法实现)
输入格式
输入一行,整数n(n代表你这组数据的个数)
输入一行,你的数据X1、X2........、Xn
输出格式:
最大子数组:Xi,X(i+1)……Xk
最大子数组的和是:sumMax
样例输入:
数据个数:9
数组为:2,4,-7,5,2,-1,2,-4,3
样例输出:
最大子数组:5,2,-1,2
最大子数组的和是:8
五、字母图形
问题描述
利用字母可以组成一些美丽的图形,下面给出了一个例子:
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。
输入格式
输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。
输出格式
输出n行,每个m个字符,为你的图形。
样例输入
5 7
样例输出
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
数据规模与约定
1 <= n, m <= 26。
六、核桃的数量
问题描述
小张是软件项目经理,他带领3个开发组。工期紧,今天都在加班呢。为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑)。他的要求是:
1. 各组的核桃数量必须相同
2. 各组内必须能平分核桃(当然是不能打碎的)
3. 尽量提供满足1,2条件的最小数量(防止闹革命嘛)
输入格式
输入包含三个正整数a, b, c,表示每个组正在加班的人数,用空格分开(a,b,c<30)
输出格式
输出一个正整数,表示每袋核桃的数量。
样例输入1
2 4 5
样例输出1
20
样例输入2
3 1 1
样例输出2
3
七、完美的代价
问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为N.只包含小写字母
输出格式
如果可能,输出最少的交换次数。
否则输出Impossible
样例输入
5
mamad
样例输出
3
八、实现用变量X(大写)代替某字符串片段的功能,并计算变量个数。(为了防止变量X与字符串中的X重名,只输入小写字符串)
例如
字符串:abcdefabc
字符串片段:bc
输入出:aXdefaX
变量个数:2
九、在小于10的素数中有3、5、7组成的等差数列,在小于30的素数中有11、17、23、29组成的等差数列。试找出区间[100,5000]内的素数构成的最大等差数列(即等差数列包含的素数个数最多)并打印输出。
十、有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)、黄(yellow)四色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法.
输入要求:
输入数据包含多个测试实例,每个测试实例占一行,由一个整数N组成,(0<n<=50)。
输出要求:
对于每个测试实例,请输出全部的满足要求的涂法,每个实例的输出占一行。
例如:
输入:
1
2
输出:
4
12
解题:
第一题
思路:当前日期为2014-11-09,定时为1000天,当天数大于366天时,从2015年开始判断是否为闰年,如果是天数减366天,否则减少365天;当天数小于366天时开始判断月份,根据是否为闰年对二月的天数进行选择;当天数小于31天时剩余天数即为日。
编写程序:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int j,i=1000,year=2014,month=11,day=9;
int a[12]={31,28,31,30,31,30,31,31,30,31,30,31};
printf("炸弹放置时间:%d年%d月%d日\n",year,month,day);
for(year=2015;i>=366;year++)
{
if(year%4==0&&year%100!=0||year%400==0)
i=i-366;
else
i=i-365;
}
i=i+9-30-31;
if(year%4==0&&year%100!=0||year%400==0)
a[1]=29;
else a[1]=28;
for(j=0;i>31&&j<12;j++)
i=i-a[j];
month=j+1;
day=i;
printf("爆炸时间为%d年%d月%d日\n",year,month,day);
system("pause");
return 0;
}
运行结果:
第二题
思路:定义struct student类型结构体用来存储姓名,学号等成员变量,定义输入、输出和查询三个函数,实现对查询特定学号的学生信息的查询。
编写程序:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct student
{
char name [10];
char number[10];
char hometown[10];
char ID[20];
int age;
char address[10];
char gender[8];
char tel[10];
};
void main()
{
void input(struct student * p);
void print(struct student * p);
int search(struct student * p,char * num);
int i;
struct student p[5];
char num[10];
input(p);
printf("\n");
print(p);
printf("\n\n请输入要查找的学号:");
gets_s(num);
i=search(p,num);
if(i==5)
printf("无此人");
else
printf ("\n姓名:%s 学号:%s\n籍贯:%s 身份证号:%s\n年龄:%d 地址:%s \n性别:%s 电话:%s\n",(*(p+i)).name, (*(p+i)).number,(*(p+i)).hometown,(*(p+i)).ID,(*(p+i)).age,(*(p+i)).address,(*(p+i)).gender,(*(p+i)).tel);
system("pause");
}
void input(struct student *p)
{
int i;
for(i=0;i<5;i++)
{
printf("请输入姓名(退出输入quit):");
gets((*(p+i)).name);
if(!strcmp((*(p+i)).name,"quit")) break;
printf("请输入学号:");
gets((*(p+i)).number);
printf("请输入籍贯:");
gets((*(p+i)).hometown);
printf("请输入身份证号:");
gets((*(p+i)).ID);fflush(stdin);
printf("请输入年龄:");
scanf("%d",&((*(p+i)).age));fflush(stdin);
printf("请输入住址:");
gets((*(p+i)).address);
printf("请输入性别:");
gets((*(p+i)).gender);
printf("请输入电话:");
gets((*(p+i)).tel);
}
}
void print(struct student * p)
{
int i=0;
for(;(i<5)&&(strcmp((*(p+i)).name,"quit"));i++)
printf("\n姓名:%s 学号:%s\n籍贯:%s 身份证号:%s\n年龄:%d 地址:%s\n性别:%s 电话:%s\n",(*(p+i)).name,
(*(p+i)).number,(*(p+i)).hometown,(*(p+i)).ID,(*(p+i)).age,
(*(p+i)).address,(*(p+i)).gender,(*(p+i)).tel);
}
int search(struct student * p,char * num)
{
int i;
for(i=0;i<=5;i++)
if(strcmp(num,(p+i)->number)==0) break; //当输入的查找num与number相等时返回i的值
return (i);
}
第三题
思路:通过对stdarg.h调用定义可变数量函数,va_list()、 va_start()、 va_end()分别为定义va_list类型变量、对num个变量初始化和对清除变量内存。
编写程序:
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
int main()
{
int sum(int num,...);
printf("sum1=%d\n",sum(4, 12, 23, 54, 76));
printf("sum2=%d\n",sum(6, 12, 34, 657, 54, 23, 54));
printf("sum3=%d\n",sum(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
system("pause");
return 0;
}
int sum(int num,...)
{
va_list p;
int sum=0;
int i;
va_start(p,num);
for(i=0;i<num;i++)
{
sum=sum+va_arg(p,int);
}
va_end(p);
return sum;
}
第五题
思路:输出规律为用for循环变量(i-j)绝对值与A的ASCII码做加法得到下一个字母的ASCII码
编写程序:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{
int i,j,n,m;
printf("请输入需要打印的字母图形的行和列: ");
scanf("%d%d",&n,&m);
for (i=0;i<n;i++) //控制行
{
for(j=0;j<m;j++) //控制列
{
printf("%c",abs(i-j)+'A'); //(i-j)绝对值与A的ASCII码加法得到下一个字母的ASCII码
}
printf("\n");
}
system("pause");
return 0;
}
第六题
思路:三个数求最小公倍数,先用辗转相除法求两个数的的最小公倍数,再和第三个数求最小公倍数,调用两次求最小公倍数函数。
编写程序:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int sum(int ,int );
int a,b,c,x,k;
printf("请输入3个开发组各组的人数: ");
scanf_s("%d%d%d",&a,&b,&c);
x=sum(a,b);
k=sum(x,c);
printf("每袋核桃的数量:%d\n",k);
system("pause");
return 0;
}
int sum(int a,int b)
{
int t,m,n,x;
m=a;
n=b;
while(b!=0) //余数不为0,继续相除,直到余数为0 //
{
t=a%b;
a=b;
b=t;
}
return m*n/a;
}