一、字符串转换成十进制整数
1、题目描述:
输入一个以#结束的字符串,本题要求滤去所有的非十六进制字符(不分大小写),组成一个新的表示十六进制数字的字符串,然后将其转换为十进制数后输出。如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数。
输入格式:
输入在一行中给出一个以#结束的非空字符串。
输出格式:
在一行中输出转换后的十进制数。题目保证输出在长整型范围内。
输入样例:
+-P-xf4+-1!#
输出样例:
-3905
2、题目分析:
- 正负判断,找到第一个十六进制数,寻找之前有没有‘-’;
- 找到所有十六进制数
- 转化为十进制数(字符转化为数字
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.总结反思:
- 判断符号是str[j]误用str[i];
- 0 的ascll码为 48 ;a 的ascll码为 97 ;A的ascll码为 65;
- 字符串储存在数组中末尾需要添加 ‘\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");
}
}