一些简单OJ:进制转换,报数字,刷快手。

一、字符串转换成十进制整数

1、题目描述:

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

输入格式:

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

输出格式:

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

输入样例:

+-P-xf4+-1!#

输出样例:

-3905

2、题目分析:

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

3、代码解决:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<math.h>
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);
}

4.总结反思:

  1. 判断符号是str[j]误用str[i];
  2. 0 的ascll码为 48 ;a 的ascll码为 97 ;A的ascll码为 65;
  3. 字符串储存在数组中末尾需要添加 ‘\0' ;

二、A + B Problem

1.题目描述

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

2.代码呈现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
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;
}

三: 你今天刷快手了吗

1.题目描述

输入格式:

在第一行给两个整数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

2.代码呈现 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
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;
        }
    }
}

四、顺时针矩阵 

1.题目描述

读入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

2.代码呈现 

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int n, ii, jj;
    scanf("%d", &n);
    int k = 1;
    int a[20][20];
    int i0, i1, j0, j1, x;
    i0 = 0; i1 = n - 1;
    j0 = 0; j1 = n - 1;
    for (x = 0; x <= n / 2; x++)
    {
        for (ii = i0, jj = j1; ii <= i1; ii++)
        {
            a[ii][jj] = k;
            k++;
        }
        for (jj = j1 - 1, ii = i1; jj >= j0; jj--)
        {
            a[ii][jj] = k;
            k++;
        }
        for (ii = i1 - 1, jj = j0; ii >= i0; ii--)
        {
            a[ii][jj] = k;
            k++;
        }
        for (ii = i0, jj = j0 + 1; jj <= j1 - 1; jj++)
        {
            a[ii][jj] = k;
            k++;
        }
        i0 = i0 + 1, i1 = i1 - 1, j0 = j0 + 1, j1 = j1 - 1;
    }
    for (ii = 0; ii < n; ii++)
    {
        for (jj = 0; jj < n; jj++)
            printf("%4d", a[ii][jj]);
        printf("\n");
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值