对方不想和你说话,并向你扔了一串数…… 而你必须从这一串数字中找到“250”这个高大上的感人数字。
输入格式:
输入在一行中给出不知道多少个绝对值不超过1000的整数,其中保证至少存在一个“250”。
输出格式:
在一行中输出第一次出现的“250”是对方扔过来的第几个数字(计数从1开始)。题目保证输出的数字在整型范围内。
输入样例:
888 666 123 -233 250 13 250 -222
输出样例:
5
Note:
骚年,在这么多对数字中找到你自己,其实还真不容易哈。这一题比较简单,但是提一个小知识点,当你用 %d 来输出一个字符时,输出的是它的 ASCII 值,但如果你用 %d 来接受它,它就强制转换成了数字了,当然这只适用于单个字符的情况。这一题不用考虑那么多,直接怼就是了。不要用字符串来接受,那样做会很麻烦,scanf 语句有空格识别的。你们可以注意到我的 count 是放在 while 的判断里的,这不是炫技,因为我试过单独列一个 count++,发现占用的运行内存比我现在的方法要大上几百 KB,这强迫症哪里能忍啊,果断改掉!
#include
int main()
{
int n, count = 0;
while (++count) { // count 放在 while 循环内,自增之后永远为增
scanf("%d", &n);
if (n == 250) {
printf("%d", count);
break;
}
}
return 0;
}
读字符还是要读字符的,我不过写出来给你们参考一下而已(真香)。
#include
#include
#include
int main()
{
char ch;
int count = 0, num = 0;
ch = getchar();
while (ch != '\n') {
if(isdigit(ch)) { // 求数字大小
ch = ch -'0';
num = num*10 + ch;
}
if (num == 250) { // 找到250,输出计数,退出循环
count ++;
printf("%d", count);
break;
}
if (ch == ' ') {
// printf("num:%d count:%d\n", num, count);
num = 0; // 遇见空格,重置 num 的值,同时计数加一
count ++;
}
ch = getchar(); // 读取下一个字符
}
return 0;
}
世界上不同国家有不同的写日期的习惯。比如美国人习惯写成“月-日-年”,而中国人习惯写成“年-月-日”。下面请你写个程序,自动把读入的美国格式的日期改写成中国习惯的日期。
输入格式:
输入在一行中按照“mm-dd-yyyy”的格式给出月、日、年。题目保证给出的日期是1900年元旦至今合法的日期。
输出格式:
在一行中按照“yyyy-mm-dd”的格式给出年、月、日。
输入样例:
03-15-2017
输出样例:
2017-03-15
Note:
之所以说 PTA 的题目好,是因为每一题看似都不难,但是想要最优是需要你去仔细思考的,本题就需要利用 scanf 函数的特性达到最优效果。
#include
int main()
{
int a, b, c;
scanf("%d-%d-%d", &a, &b, &c);
printf("%d-%02d-%02d\n", c, a, b);
return 0;
}
天梯图书阅览室请你编写一个简单的图书借阅统计程序。当读者借书时,管理员输入书号并按下S键,程序开始计时;当读者还书时,管理员输入书号并按下E键,程序结束计时。书号为不超过1000的正整数。当管理员将0作为书号输入时,表示一天工作结束,你的程序应输出当天的读者借书次数和平均阅读时间。
注意:
由于线路偶尔会有故障,可能出现不完整的纪录,即只有S没有E,或者只有E没有S的纪录,系统应能自动忽略这种无效纪录。另外,题目保证书号是书的唯一标识,同一本书在任何时间区间内只可能被一位读者借阅。
输入格式:
输入在第一行给出一个正整数N(≤10),随后给出N天的纪录。每天的纪录由若干次借阅操作组成,每次操作占一行,格式为:
书号([1, 1000]内的整数) 键值(S或E) 发生时间(hh:mm,其中hh是[0,23]内的整数,mm是[0, 59]内整数)
每一天的纪录保证按时间递增的顺序给出。
输出格式:
对每天的纪录,在一行中输出当天的读者借书次数和平均阅读时间(以分钟为单位的精确到个位的整数时间)。
输入样例:
3
1 S 08:10
2 S 08:35
1 E 10:00
2 E 13:16
0 S 17:00
0 S 17:00
3 E 08:10
1 S 08:20
2 S 09:00
1 E 09:20
0 E 17:00
输出样例:
2 196
0 0
1 60
Note:
本题有三个坑点,别问我我怎么知道的,我也是搜别人博客才知道的。。。第一个就是借阅时间只算最后一次借出到最早一次归还,第二个就是结果要四舍五入的输出。另外做题过程中自己发现的一些小问题,float 不能进行 ++ 操作,所以 count 要定义成 int 类型;四舍五入那里 int 要加括号。而且要注意这题有一个测试案例是有00:00借书的,即 time 的值为0所以我选择初始化数组的值为-1,但正常情况下谁会00:00来借书啊。。。算是一个 bug吧。
memset 是对较大的数组或结构体进行清零初始化的最快方法,因为它是直接对内存进行操作的。字符串数组就可以用 ‘\0’ 来初始化,虽然参数 c 要求是一个整数,但是整型和字符型是互通的。由于赋值为 ‘\0’ 和 0 是等价的,因此字符 ‘\0’ 在内存中就是 0。所以在 memset 中初始化为 0 也具有结束标志符 ‘\0’ 的作用,所以通常我们就写“0”。
#include
#include
int main()
{
int N, num, count;
float hh, mm, alltime, time[1000];
char s[0]; // 定义字符串数组来接收管理员的按键操作
scanf("%d", &N);
while (N--) {
count = alltime = 0; // 后一天,所有数据初始化
memset(time, -1, sizeof(time)); // 清空数组里的残余值,也算初始化
while (1) {
scanf("%d%s %f:%f", &num, s, &hh, &mm); // 字符串数组会忽视前面的空格
if (num == 0) break;
else if (s[0] == 'S')
time[num] = hh*60 + mm; // 第二次借书的时间可以覆盖前一次
else if (s[0] == 'E' && time[num] >= 0) {
alltime += (hh*60 + mm - time[num]); // 借阅时间增加
count ++; // 借出的书到换回来一个过程才算一次借阅
time[num] = -1; // 置0标记已经归还过,不能更新归还时间
}
}
if (count)
printf("%d %d\n", count, (int)(alltime/count + 0.5)); // 输出结果,平均借阅时间四舍五入输出
else
printf("0 0\n");
}
}
大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:
现要求你编写一个稳赢不输的程序,根据对方的出招,给出对应的赢招。但是!为了不让对方输得太惨,你需要每隔K次就让一个平局。
输入格式:
输入首先在第一行给出正整数K(≤10),即平局间隔的次数。随后每行给出对方的一次出招:ChuiZi代表“锤子”、JianDao代表“剪刀”、Bu代表“布”。End代表输入结束,这一行不要作为出招处理。
输出格式:
对每一个输入的出招,按要求输出稳赢或平局的招式。每招占一行。
输入样例:
2
ChuiZi
JianDao
Bu
JianDao
Bu
ChuiZi
ChuiZi
End
输出样例:
Bu
ChuiZi
Bu
ChuiZi
JianDao
ChuiZi
Bu
Note:
间隔 n 次,则从一次平局到下一次平局需要加 n + 1。不能用 gets() 的原因在于 scanf 以回车或空格结束,然后将操作存入缓冲区,用 gets() 就会接收到结束符从而出错。也可以在 k 输入后加一个 getchar() 接受回车,然后后面全部用 get(s) 来接受字符串,也不会产生这种问题。
#include
int main()
{
// 边读取字符串边输出结果,同时计数,计数到了输出一次平局,然后计数置0
char s[8];
int k, i = 0; // i 用于计数
scanf("%d", &k);
scanf("%s", s); // 不能用 gets(),否则会把回车读进去
while (s[0] != 'E') {
i ++; // i 至少为1,否则第一局就是平局
if ((s[0] == 'B' && i%(k + 1) != 0) || (s[0] == 'J' && i%(k + 1) == 0)) printf("JianDao\n");
if ((s[0] == 'J' && i%(k + 1) != 0) || (s[0] == 'C' && i%(k + 1) == 0)) printf("ChuiZi\n");
if ((s[0] == 'C' && i%(k + 1) != 0) || (s[0] == 'B' && i%(k + 1) == 0)) printf("Bu\n");
scanf("%s", s); // 读取下一次出招
if (i%(k + 1) == 0) i = 0; // 到达间隔,计数置0
}
return 0;
}
这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如,111111就可以被13整除。 现在,你的程序要读入一个整数x,这个整数一定是奇数并且不以5结尾。然后,经过计算,输出两个数字:第一个数字s,表示x乘以s是一个光棍,第二个数字n是这个光棍的位数。这样的解当然不是唯一的,题目要求你输出最小的解。
提示:
一个显然的办法是逐渐增加光棍的位数,直到可以整除x为止。但难点在于,s可能是个非常大的数 —— 比如,程序输入31,那么就输出3584229390681和15,因为31乘以3584229390681的结果是111111111111111,一共15个1。
输入格式:
输入在一行中给出一个不以5结尾的正奇数x(<1000)。
输出格式:
在一行中输出相应的最小的s和n,其间以1个空格分隔。
输入样例:
31
输出样例:
3584229390681 15
Note:
结果太大了,所以不可能正常的让机器去真计算,所以要写一个算法来模拟除法运算的过程。一开始我定义了一个很大字符数组来接收运算中的商,然后绞尽脑汁儿想了很久怎么把把商存入字符数组,脑袋痛就睡着了。梦中惊醒,我真是太 sd 了,我为什么要存入数组呀?直接输出不就行了吗。。。脑子抽的我真不适合学编程啊。而且题目中也没有暗示用字符数组来保存运算过程中的商,所以千万不要再像我一样动不动就字符数组了。。。第一个 while 循环那里,不要令 x >= s,因为输入的数 x 有可能本身就是一个光棍,此时商就是1,位数就是 x 的位数。但是因为 s 自增会变成 x 一样大,因为循环为真的原因还会自增一次,就导致结果错误了。
#include
int main()
{
int x, s = 0, n = 0; // s 记录余数,n 用来记录位数
scanf("%d", &x);
if (x%5 == 0 || x%2 == 0 || x >= 1000) return 0;// 无效输入退出程序
while (x > s) { // s 小于 x,则补1自增直到大于 x
s = s*10 + 1;
n ++; // 同时位数自增
}
while(1) {
printf("%d", s/x); // 计算商并输出
s = s%x; // 令 s 等于余数
if (s == 0) break; // 余数为0,退出循环
s = s*10 + 1; // 除法的规则,s 只需要自增一位肯定大于 x
n ++; // 位数加一
}
printf(" %d", n); // 输出位数,别忘记空格
return 0;
}
你永远叫不醒一个装睡的人 —— 但是通过分析一个人的呼吸频率和脉搏,你可以发现谁在装睡!医生告诉我们,正常人睡眠时的呼吸频率是每分钟15-20次,脉搏是每分钟50-70次。下面给定一系列人的呼吸频率与脉搏,请你找出他们中间有可能在装睡的人,即至少一项指标不在正常范围内的人。
输入格式:
输入在第一行给出一个正整数N(≤10)。随后N行,每行给出一个人的名字(仅由英文字母组成的、长度不超过3个字符的串)、其呼吸频率和脉搏(均为不超过100的正整数)。
输出格式:
按照输入顺序检查每个人,如果其至少一项指标不在正常范围内,则输出其名字,每个名字占一行。
输入样例:
4
Amy 15 70
Tom 14 60
Joe 18 50
Zoe 21 71
输出样例:
Tom
Zoe
Note:
唉我真是净挑些简单的题目做。。。没什么好记录的。
#include
#include
int main()
{
int i, n, flag;
char name[4];
int br, pl;
scanf("%d", &n);
for (i = 0; i < n; i++) {
flag = 0;
scanf("%s %d %d", name, &br, &pl);
if (br < 15 || br > 20) flag = 1;
if (pl < 50 || pl > 70) flag = 1;
if (flag) printf("%s\n", name);
memset(name, '\0', sizeof(name));
}
return 0;
}
哈哈哈哈哈哈哈你要是不往下面看你就吃亏拉,其实这题更简单的做法是下面这样的,甚至都不要清空数组哈哈哈。直接用逆否做就行啦,我们知道呼吸15到20之间且脉搏50到70之间就不算睡觉,它的逆否就是非呼吸15到20之间或脉搏50到70之间。用该逆否做 if 的判断就可以啦。
#include
int main()
{
int i, n, br, pl;
char name[4];
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%s %d %d", name, &br, &pl);
if (!(br <= 20 && br >= 15)||!(pl <= 70 && pl >= 50))
printf("%s\n", name);
}
return 0;
}
给定两个矩阵A和B,要求你计算它们的乘积矩阵AB。需要注意的是,只有规模匹配的矩阵才可以相乘。即若A有Ra行、Ca列,B有Rb行、Cb列,则只有Ca与Rb相等时,两个矩阵才能相乘。
输入格式:
输入先后给出两个矩阵A和B。对于每个矩阵,首先在一行中给出其行数R和列数C,随后R行,每行给出C个整数,以1个空格分隔,且行首尾没有多余的空格。输入保证两个矩阵的R和C都是正数,并且所有整数的绝对值不超过100。
输出格式:
若输入的两个矩阵的规模是匹配的,则按照输入的格式输出乘积矩阵AB,否则输出Error: Ca != Rb,其中Ca是A的列数,Rb是B的行数。
输入样例1:
2 3
1 2 3
4 5 6
3 4
7 8 9 0
-1 -2 -3 -4
5 6 7 8
输出样例1:
2 4
20 22 24 16
53 58 63 28
输入样例2:
3 2
38 26
43 -5
0 17
3 2
-11 57
99 68
81 72
输出样例2:
Error: 2 != 3
Note:
做完之后一直有两个测试过不去,调试了很久发现二维数组用的 char 定义,用字符串习惯了。。。
#include
int main()
{
// 二维数组刚好可以表示矩阵,一维表示行号,二维表示列号,因此矩阵题目二维矩阵是最好的
int ra, ca, rb, cb, i, j, k; //定义 A,B 矩阵的行值列值
int A[100][100], B[100][100], C[100][100] = {0};
scanf("%d%d", &ra, &ca); // 输入不一定非要空格的,scanf 能识别
for (i = 0; i < ra; i++)
for (j = 0; j < ca; j++)
scanf("%d", &A[i][j]);
scanf("%d%d", &rb, &cb);
for (i = 0; i < rb; i++)
for (j = 0; j < cb; j++)
scanf("%d", &B[i][j]);
if (ca != rb) { // 不能进行矩阵乘法
printf("Error: %d != %d", ca, rb);
return 0;
}
printf("%d %d\n", ra, cb);
for (i = 0; i < ra; i++) { // 先行
for (j = 0; j < cb; j++) { // 后列
for (k = 0; k < ca; k++) // 行列式乘法规律,中间数增到 ca - 1 为止
C[i][j] += A[i][k]*B[k][j]; // 计算 C 的每一项
printf("%d", C[i][j]);
if (j + 1 != cb) printf(" "); // 输出空格
}
if (i + 1 != ra) printf("\n"); // 换行
}
return 0;
}
给定一个完全由小写英文字母组成的字符串等差递增序列,该序列中的每个字符串的长度固定为 L,从 L 个 a 开始,以 1 为步长递增。例如当 L 为 3 时,序列为 { aaa, aab, aac, …, aaz, aba, abb, …, abz, …, zzz }。这个序列的倒数第27个字符串就是 zyz。对于任意给定的 L,本题要求你给出对应序列倒数第 N 个字符串。
输入格式:
输入在一行中给出两个正整数 L(2 ≤ L ≤ 6)和 N(≤105)。
输出格式:
在一行中输出对应序列倒数第 N 个字符串。题目保证这个字符串是存在的。
输入样例:
3 7417
输出样例:
pat
Note:
直接令一个整型数据等于double类型数据的计算结果会丢失精读,不准确。在用 z 来表示偏移的字母时,理论上是偏移多少减多少。这一题要求的是倒数,比如那一位应该是 x,则 z 的 ASCII 值应该减去2,但实际上 x 是倒数第3位,所以在输入的 N 应该要处理完,即先减去1后才能得到正确的倒数位的字母。
#include
#include
double main()
{
double L, N, n, yu, digit;
scanf("%lf %lf", &L, &N);
n = L - 1; // n 题目保证字符串是存在的
N = N - 1; // 即 N 肯定是小于 pow(26, n),所以直接从 n - 1算
while (1) {
digit = floor(N/(pow(26, n))); // 将整数商部分存入 digit,即为对应为的位置偏移,同时要向下取整
char b = 'z'; // 这里是将字符 b 赋值字符 z,写在表达式里的 'z' 是 z 的 ASCII 码值
printf("%c", b - (int)digit); // ASCII码的得转换是整型运算
yu = pow(26, n); // 如果在这里用 int 定义 yu 会丢失精度产生计算偏差
N = (int)N%(int)yu; // % 两边必须是整型变量
n --; // 注意 n = 0 是要参与运算的,所以判定是 n 是否小于0
if (n < 0) break;
}
return 0;
}
一定要自己写一遍哦~~~