PTA/OJ

1、然后是几点

题目描述:

有时候人们用四位数字表示一个时间,比如 1106 表示 11 点零 6 分。现在,你的程序要根据起始时间和流逝的时间计算出终止时间。

读入两个数字,第一个数字以这样的四位数字表示当前时间,第二个数字表示分钟数,计算当前时间经过那么多分钟后是几点,结果也表示为四位数字。当小时为个位数时,没有前导的零,例如 5 点 30 分表示为 530;0 点 30 分表示为 030。注意,第二个数字表示的分钟数可能超过 60,也可能是负数。

输入格式:

输入在一行中给出 2 个整数,分别是四位数字表示的起始时间、以及流逝的分钟数,其间以空格分隔。注意:在起始时间中,当小时为个位数时,没有前导的零,即 5 点 30 分表示为 530;0 点 30 分表示为 030。流逝的分钟数可能超过 60,也可能是负数。

输出格式:

输出不多于四位数字表示的终止时间,当小时为个位数时,没有前导的零。题目保证起始时间和终止时间在同一天内。

代码呈现:

#include 
int main () {
    int N,M,h,m,r;
    scanf("%d %d", &N, &M);
    h = N/100; // 这里N/100赋值给h,h就是从0点开始经过的时间的小时部分
    m = N%100; // 这里N%100赋值给m,m就是从0点开始经过的时间的分钟部分
    m += M;
    if (m >=60) {  // 如果加上流逝的分钟数后,分钟数大于等于60,则需要进位。
        h += m/60;
        m %= 60;
    }
    else if (m < 0) { // 如果加上流逝的分钟数后,分钟数小于0,则需要借位。
        m = -m;       // 先给m取反,方便计算。
        r = (m-1)/60+1; // 当m属于[1,60],借1位; m属于[61,119]借2位, 所以有这样的公式
        h -= r;    
        m = 60*r-m;
    }
    printf("%d%02d", h%24, m); 
    return 0;
}

2.计算火车运行时间

题目描述:

本题要求根据火车的出发时间和达到时间,编写程序计算整个旅途所用的时间。

输入格式:

输入在一行中给出2个4位正整数,其间以空格分隔,分别表示火车的出发时间和到达时间。每个时间的格式为2位小时数(00-23)和2位分钟数(00-59),假设出发和到达在同一天内。

输出格式:

在一行输出该旅途所用的时间,格式为“hh:mm”,其中hh为2位小时数、mm为2位分钟数。

代码呈现:

#include 
int main(void) {
    int a1,a2,hh,mm;
        scanf("%d %d",&a1,&a2);
        hh=a2/100-a1/100;
        mm=a2%100-a1%100;
        if(mm<0){
            mm=mm+60;
            hh=hh-1;
        }
        printf("%02d:%02d",hh,mm);
    return 0;
}

3.兔子繁衍问题

题目描述:

一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死,请问第1个月出生的一对兔子,至少需要繁衍到第几个月时兔子总数才可以达到N对?

输入格式:

输入在一行中给出一个不超过10000的正整数N。

输出格式:

在一行中输出兔子总数达到N最少需要的月数。

代码呈现:

// 1  1  2  3  5  8  13
// 0  0  +1 +1 +2 +3 +5
#include 
int main()
{
	int N;
	int a = 1;
	int b = 1;
	int x = 2;
	int t = 2;
	scanf("%d", &N);
	if (N == 1)
		printf("1");
	else
		while (x <= N)
		{
			x = a + b;
			a = b;
			b = x;
			t++;
			if (x >= N)
			{
				printf("%d", t);
				break;
			}
		}
}

4.顺时针矩阵

题目描述

读入20内正整数正整数n,输出顺时针分布的矩阵。矩阵内容为1,2,到n*n。

输入格式:

每个实例包含一个20内正整数。

输出格式:

顺时针分布的矩阵,每个数据占4位。

输入样例:

7

输出样例:

19 20 21 22 23 24 1
18 37 38 39 40 25 2
17 36 47 48 41 26 3
16 35 46 49 42 27 4
15 34 45 44 43 28 5
14 33 32 31 30 29 6
13 12 11 10 9 8 7

代码呈现

#include
int main() {
	int x, y, n, m;
	int N[20][20];
	int math = 1;
	scanf("%d", &n);
	if (n % 2 == 0)
		m = n / 2;
	else
		m = n / 2 + 1;
	for (int i = 0; i < m; i++) {
		for (x = i, y = n - i - 1; x < n - i - 1||x==m-1; x++)
			N[x][y] = math++;
		for (x = n - i - 1, y = n - i - 1; y > i; y--)
			N[x][y] = math++;
		for (x = n - i - 1, y = i; x > i; x--)
			N[x][y] = math++;
		for (x = i, y = i; y < n - i - 1; y++)
			N[x][y] = math++;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++)
			printf("%4d", N[i][j]);
		printf("\n");
	}
}

5.字符串转换成十进制整数

题目描述:

输入一个以#结束的字符串,本题要求滤去所有的非十六进制字符(不分大小写),组成一个新的表示十六进制数字的字符串,然后将其转换为十进制数后输出。如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数。

输入格式:

输入在一行中给出一个以#结束的非空字符串。

输出格式:

在一行中输出转换后的十进制数。题目保证输出在长整型范围内。

输入样例:

+-P-xf4+-1!#

输出样例:

-3905

题目分析:

正负判断,找到第一个十六进制数,寻找之前有没有‘-’;
找到所有十六进制数
转化为十进制数(字符转化为数字

代码解决:

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
int main() {
    char str[80];
    char str2[80];
    fgets(str,80,stdin);
    int i = 0;
    int t = 0;
    int sum = 0;
    for (i = 0; str[i] != '#'; i++) {
        if ((str[i] >= '0' && str[i] <= '9') || (str[i] >= 'a' && str[i] <= 'f') || (str[i] >= 'A' && str[i] <= 'F'))
            break;
    }
    for (int j = 0; j < i; j++) {
        if (str[j] == '-') {
            printf("-");
            break;
        }
    }
    for (i = 0; str[i] != '#'; i++) {
        if ((str[i] >= '0' && str[i] <= '9') || str[i] >= 'a' && str[i] <= 'f' || str[i] >= 'A' && str[i] <= 'F') {
            str2[t++] = str[i];
        }
    }
    str2[t] = '\0';
    for (int j = 0; j < t; j++) {
        if (str2[j] >= '0' && str2[j] <= '9')
            sum += (str2[j] - 48) * (int)pow(16, t - 1 - j);
        else if (str2[j] >= 'a' && str2[j] <= 'f')
            sum += (str2[j] - 97+10) * (int)pow(16, t - 1 - j);
        else
            sum += (str2[j] - 65+10) * (int)pow(16, t - 1 - j);
    }
    printf("%d", sum);
}

6.A + B Problem

题目描述

Calculate A + B.

输入格式

Each line will contain two integers A and B. Process to end of file.

输出格式

For each case, output A + B in one line.

Sample Input

1 1

Sample Output

2

代码呈现

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
int x[200] = { 0 }, y[200] = { 0 }, z[210] = { 0 };//将数组元素全部初始化为0
int main()
{
	char a[200], b[200];//把大数存储为字符串形式的数组 
	int len, len1, len2;//定义三个长度,后续用于存储字符串长度
	while (scanf("%s%s", a, b) != EOF) {//输入a,b字符串
		len1 = (int)strlen(a);//让len1为字符串a的长度,也就是大数a的位数
		len2 = (int)strlen(b);//让len2为字符串b的长度,也就是大数b的位数
		int i, j = 0, k = 0;//定义循环变量
		for (i = len1 - 1; i >= 0; i--)//让下标从长度最后一位开始循环,把大数倒序储存到数组中,即字符串为123456,则数组为654321
		{
			x[j] = a[i] - '0';//把数组a倒着储存在数组x中
			j++;//递减,然后循环,完成数组x倒叙储存数组a的操作
		}
		for (i = len2 - 1; i >= 0; i--)//以同样的方法,将数组b倒叙储存为数组y 
		{
			y[k] = b[i] - '0';
			k++;
		}
		if (len1 > len2)//比较数组长度(也就是大数大小);让len等于最长的长度
			len = len1;
		else
			len = len2;
		i = 0;//从最低位(个位)开始进行计算
		int m = 0;
		for (i = 0; i < len; i++)//循环相加并储存在新数组z中,短的len不够补0,也就是给原来的大数前加0(不影响大数大小) 
		{
			z[i] = (x[i] + y[i] + m) % 10;//将所得数的个位存到数组z[i]中去
			if (x[i] + y[i] + m >= 10)//判断两个位上的数相加是不是超过10,如果过了,就进1,没过,就不进
				m = 1;//加在下一次循环中,类似于过10进1;
			else
				m = 0;
		}
		if (x[i - 1] + y[i - 1] + m >= 10)//判断运算的最大位的和是否>=10 
			z[i] = 1;//数组为i位时,下标是从0到i-1,如果最大一位的和过10了,就多一位数组元素存放过10进的1
		else
			i = i - 1;//如果没过,最大位就是i-1
		for (; i >= 0; i--)//让数组下标从小到大循环输出,倒序输出数组z
			printf("%d", z[i]);
		printf("\n");
	}
	return 0;
}

7.你今天刷快手了吗

输入格式:

在第一行给两个整数n和m(1≤n≤1000,0≤m≤10^4),n代表你们班上的人数,m代表数据的条数,接下来m行每行给一组数据,格式为:学号 进入时间 退出时间,你们班的学号为从0~n-1编号并且为三位数。题目保证给出的所有时间均是同一天之内的。

输出格式:

将每个同学一天中刷快手的总时间从小到大排序输出(若出现并列情况,则按学号从小到大输出),输出格式为:学号 时间,最后输出最长的时间。

注:输出和输出的学号为三位数(不足三位补前导0),输出的时间格式为:00:00:00

输入样例1:

3 5
000 19:48:30 19:59:24
002 18:45:40 19:01:20
000 21:32:28 21:53:30
001 12:30:16 12:43:19
001 13:05:36 13:37:33

输出样例1:

001 00:45:00
000 00:31:56
002 00:15:40

输入样例2:

3 5
000 12:03:31 12:13:12
002 12:00:28 12:54:41
001 16:04:44 16:34:47
001 07:30:29 07:54:39
000 23:17:18 23:29:33

输出样例2:

001 00:54:13
002 00:54:13
000 00:21:56

代码呈现

#define _CRT_SECURE_NO_WARNINGS 1
#include
int time(int h1, int m1, int s1, int h2, int m2, int s2) {
    return (h2 * 60 * 60 + m2 * 60 + s2) - (h1 * 60 * 60 + m1 * 60 + s1);    //计算经过的总时长并统一为秒
}
int main() {
    int n, m;
    int k;
    int num;
    int temp;
    int h1, h2, m1, m2, s1, s2;
    int N[1000][2];
    int t = 0;
    int flag = 1;
 
    for (int i = 0; i < 1000; i++) {
        N[i][0] = i;                                 //下标为0记录学号
        N[i][1] = 0;                                 //下标为1记录时长
    }
    scanf("%d%d", &n, &m);
    if (m == 0) {                                    //0条记录特殊情况
        for (int i = 0; i < n; i++) {
            printf("%03d 00:00:00\n", i);
        }
        return 0;
    }
    for (int i = 0; i < m; i++) {
        scanf("%d", &num);
        scanf("%d:%d:%d", &h1, &m1, &s1);
        scanf("%d:%d:%d", &h2, &m2, &s2);
        for (int j = 0; j < t; j++)                  //是否已有记录的学号
        {
            if (num == N[j][0]) {
                N[j][1] += time(h1, m1, s1, h2, m2, s2);
                flag = 0;
                break;
            }
        }
        if (flag == 0) {                            //如果学号已记录跳过接下来记录的操作
            flag = 1;
            continue;
        }
        N[t][0] = num;                              //记录新学号和时长
        N[t][1] += time(h1, m1, s1, h2, m2, s2);
        t++;
    }
    for (int i = 0; i < t - 1; i++)                     //选择排序
    {
        k = i;
        for (int j = i + 1; j < t; j++)
        {
            if (N[j][1] > N[k][1])                     
            {
                k = j;
            }
            if (N[j][1] == N[k][1]) {                  //相同时间按照学号排序
                if (N[j][0] < N[k][0])
                    k = j;
            }
        }
        if (k != i)
        {
            temp = N[k][1];                           //学号和时间交换
            N[k][1] = N[i][1];
            N[i][1] = temp;
            temp = N[k][0];
            N[k][0] = N[i][0];
            N[i][0] = temp;
        }
    }
 
    for (int i = 0; i < t; i++) {
        printf("%03d %02d:%02d:%02d\n", N[i][0], N[i][1] / 3600, N[i][1] / 60 % 60, N[i][1] % 60);
    }
    if (t < n) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < t; j++) {                  //每有一个未记录的学号输出一条
                if (i == N[j][0])
                    flag = 0;
            }
            if (flag == 1) {
                printf("%03d 00:00:00\n", i);
            }
            else
                flag = 1;
        }
    }
}

你可能感兴趣的:(算法,学习,c语言,数据结构)