1001 害死人不偿命的(3n+1)猜想 1002 写出这个数
C语言狗都不写
PAT乙级原来和数据结构锤子关系都没有啊,但我没写过C语言,就当学C了。
1001 害死人不偿命的(3n+1)猜想
卡拉兹(Callatz)猜想:
对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……
我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?
输入格式:
每个测试输入包含 1 个测试用例,即给出正整数 n 的值。
输出格式:
输出从 n 计算到 1 需要的步数。
输入样例:
3
输出样例:
5
题解:
#include<stdio.h>
int main()
{
int n;
int i = 0;
scanf("%d", &n);
while (n != 1)
{
if (n % 2 == 1)
{
n = (3*n + 1) / 2;
}
else
{
n = n / 2;
}
i++;
}
printf("%d", i);
return 0;
}
1002 写出这个数
读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。
输入格式:
每个测试输入包含 1 个测试用例,即给出自然数 n 的值。这里保证 n 小于 10^100。
输出格式:
在一行内输出 n 的各位数字之和的每一位,拼音数字间有 1 空格,但一行中最后一个拼音数字后没有空格。
输入样例:
1234567890987654321123456789
输出样例:
yi san wu
题解:
#include<stdio.h>
int main()
{
int sum = 0;
int n[5];
char s[100];
scanf("%s", &s);
for (int i = 0; i < 100, s[i] != '\0'; i++)///创建空字符串,默认为'\0'
{
sum = sum + (s[i] - '0');///字符型转为ascii码,减一个字符型的0就可以做到
}
char cn[10][5] = { "ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu" };///二维数组用来放一个个字符串
int j = 0;
while (sum)
{
int temp = sum % 10;
sum = sum / 10;///先取余数再整除,获得每一位数字
n[j] = temp;
j++;
}
for (j = j - 1; j >= 0; j--)///反向打印得汉语
{
if (j != 0) {
printf("%s ", cn[n[j]]);
}
else {
printf("%s", cn[n[j]]);
}
}
return 0;
}
总结
恶心坏了,c语言怎么这么难写,最难受的是printf的规范,python一句话搞定,c语言打半天,数据类型规范的一逼,有一点点不一样就报错。
今天算是初步熟悉了c语言,用了scanf和printf,用了字符串的二维数组,用了for和while循环,用了ifelse判断,具体的就不写了。。数据类型真是麻烦的要死,但愿写多了能习惯吧。
3.16补:
发现了一个重要的问题,现总结如下:
第二题的这部分本来是这样写的,但多次报错
for (int i = 0; i < 100,; i++)///创建空字符串,默认为'\0'
{
if( s[i] != '\0')
{sum = sum + (s[i] - '0');}///字符型转为ascii码,减一个字符型的0就可以做到
}
之所以不对,是因为scanf在获得输入后赋值给s字符数组,这时s数组的内容是这样的['1','2','3','/0','cc','cc'……]
前三个元素是输入,第四个元素是代表数组结束的结束符,而后面的是占位符。
如果用以上写法,数组就越界了,程序就崩溃了,打印就烫烫烫了。(cc在windows编码中对应的是“烫”字)
正确的写法是
for (int i = 0;s[i] != '\0'; i++)///创建空字符串,默认为'\0'
{
sum = sum + (s[i] - '0');///字符型转为ascii码,减一个字符型的0就可以做到
}
i<100是根本没必要的,在for循环识别到结束符'\0'时,循环结束。