卡拉兹(Callatz)猜想:
对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把
(3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在
1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命
想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),
以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……我
们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简
单地数一下,需要多少步(砍几下)才能得到 n=1?
输入格式:
每个测试输入包含 1 个测试用例,即给出正整数 n 的值。
输出格式:
输出从 n 计算到 1 需要的步数。
输入样例:
3
输出样例:
5
#include
int main(){
//num或step表示需要的步数
int n, num = 0;//step = 0
scanf("%d", &n);//输入正整数n
while(n != 1){//当n=1时,则退出循环
//判断整数n的奇偶性
if((n % 2) == 0){//n为偶数时
//因为n为偶数,则n可整除2或者说(n/2)必为整数。
n /= 2;//等价写法:n = n / 2
num++;//需要的步数自增1
}else{//n为奇数时
//因为n为奇数,则3n也为奇数,所以(3n+1)必为偶数,
//即(3n+1)可整除2或者说((3n+1)/2)必为整数。
n = (3 * n + 1) / 2;
num++;//需要的步数自增1
}
//step++;//需要的步数自增1
}
//输出需要的步数
printf("%d\n", num);//step
return 0;
}
为了用事实说明挖掘机技术到底哪家强,PAT 组织了一场挖掘机技能大赛。
现请你根据比赛结果统计出技术最强的那个学校。
输入格式:
输入在第 1 行给出不超过10^5的正整数 N,即参赛人数。随后 N 行,每行给出一位
参赛者的信息和成绩,包括其所代表的学校的编号(从 1 开始连续编号)、及其比
赛成绩(百分制),中间以空格分隔。
输出格式:
在一行中给出总得分最高的学校的编号、及其总分,中间以空格分隔。
题目保证答案唯一,没有并列。
输入样例:
6
3 65
2 80
1 100
2 70
3 40
3 0
输出样例:
2 150
#include
//因为正整数N不超过10^5=100000,所以可以将maxn赋值为100010。
const int maxn = 100010;//定义整型常量maxn,表示数组school的最大长度
//将数组school的所有元素初始化为0是对学校的比赛成绩累加求和的前提条件。
int school[maxn] = {0};//定义整型数组school并将该数组的所有元素初始化为0
int main(){
//n即为正整数N,表示输入记录的行数;
//schID表示学校的编号;score表示学校的比赛成绩。
int n, schID, score;
scanf("%d", &n);//输入n
//循环输入学校的编号和比赛成绩,即连续输入n行记录
for(int i = 0; i < n; i++){//当i=n时,则退出循环
scanf("%d %d", &schID, &score);//输入学校的编号和比赛成绩
//因为学校的编号schID是从1开始的连续编号,所以可以将schID作为数组school中元素的位序。
school[schID] += score;//对编号为schID的学校的比赛成绩累加求和
//等价写法:school[schID] = school[schID] + score
}
//k表示求和后比赛成绩最大的学校的编号;MAX表示求和后最大的比赛成绩
int k = 1, MAX = -1;
//数组school的最大长度大于输入记录的行数,所以在下面的循环中不会发生数组的越界问题。
for(int i = 1; i <= n; i++){//当i>n时,则退出循环
if(school[i] > MAX){//通过循环依次遍历数组中的所有元素,来寻找求和后最大的比赛成绩
MAX = school[i];//更新MAX的值
k = i;//更新k的值
}
}
//输出k和MAX
printf("%d %d\n", k, MAX);
return 0;
}
题目描述
输入一个数n,然后输入n个数值各不相同,再输入一个值x,输出这个值在这个数组中的下标(从0开始,若不在
数组中则输出-1)。
输入
测试数据有多组,输入n(1<=n<=200),接着输入n个数,然后输入x。
输出
对于每组输入,请输出结果。
样例输入
4
1 2 3 4
3
样例输出
2
#include
int main(){
int n;//定义整型变量n,表示输入各不相同的数值的个数
scanf("%d", &n);//输入n
int num[n];//定义整型数组num,用于存储输入的数值
//连续输入n个各不相同的数值
for(int i = 0; i < n; i++){//当i=n时,则退出循环
scanf("%d", &num[i]);//输入数值
}
int x;//定义整型变量x,表示要在数组num中查找的数值
scanf("%d", &x);//输入x
int j;//定义整型变量j,表示数组num的下标
for(j = 0; j < n; j++){//当j=n时,则退出循环
if(x == num[j]){//通过循环依次遍历数组中的所有元素,来寻找与x相等的元素
printf("%d\n", j);//输出与x相等的元素所对应的数组下标
break;//退出循环
}
}
if(j == n){//若j=n,则表示在数组num中未找到与x相等的元素
printf("%d\n", -1);//若x不在数组num中,则输出-1
}
return 0;
}
或
#include
//因为1<=n<=200,所以可以将maxn赋值为210.
const int maxn = 210;//定义整型常量maxn,表示数组a的最大长度
int a[maxn];//定义整型数组a,用于存储输入的数值
int main(){
//n表示输入各不相同的数值的个数;x表示表示要在数组num中查找的数值
int n, x;//定义整型变量n和x
//多点测试
while(scanf("%d", &n) != EOF){//输入n时,键盘输入Ctrl+Z可退出循环
//连续输入n个各不相同的数值
for(int i = 0; i < n; i++){//当i=n时,则退出循环
scanf("%d", &a[i]);//输入数值
}
scanf("%d", &x);//输入x
int k;//定义整型变量k,表示数组a的下标
for(k = 0; k < n; k++){//当k=n时,则退出循环
if(a[k] == x){//通过循环依次遍历数组中的所有元素,来寻找与x相等的元素
printf("%d\n", k);//输出与x相等的元素所对应的数组下标
break;//退出循环
}
}
if(k == n){//若k=n,则表示在数组num中未找到与x相等的元素
printf("-1\n");//若x不在数组num中,则输出-1
}
}
return 0;
}
美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总
统。2014 年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正
方形。现在你也跟他一起画吧!
输入格式:
输入在一行中给出正方形边长 N(3≤N≤20)和组成正方形边的某种字符 C,间隔一个空格。
输出格式:
输出由给定字符 C 画出的正方形。但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出
的行数实际上是列数的 50%(四舍五入取整)。
输入样例:
10 a
输出样例:
aaaaaaaaaa
a a
a a
a a
aaaaaaaaaa
#include
#include
int main(){
int n;//定义整型变量n,表示正方形边长 N,即输出的列数
char c;//定义字符型变量c,表示组成正方形边的字符 C
scanf("%d %c", &n, &c);//输入n和c
//连续输出n个组成正方形边的字符 C
for(int i = 0; i < n; i++){//当i=n时,则退出循环
printf("%c", c);//输出组成正方形边的字符 C
}
printf("\n");//输出换行
//因为输出的行数实际上是列数的50%,则输出的行数为(n/2);
//因为题目要求四舍五入取整,所以可以使用round()函数来计算要输出的行数;
//因为round()函数的参数应为double类型,所以(n/2)应写为(n/2.0);
//综上所述,总共要输出的行数为round(n / 2.0)。
int m = round(n / 2.0) - 2;//定义整型变量m,表示除第一行和最后一行之外的要输出的行数
//连续输出m行具有一定规律的字符
for(int i = 0; i < m; i++){//当i=m时,则退出循环
printf("%c", c);//输出组成正方形边的字符 C
//连续输出(n-2)个空格
for(int j = 0; j < (n - 2); j++){//当j=(n-2)时,则退出循环
printf(" ");//输出空格
}
printf("%c", c);//输出组成正方形边的字符 C
printf("\n");//输出换行
}
//连续输出n个组成正方形边的字符 C
for(int i = 0; i < n; i++){//当i=n时,则退出循环
printf("%c", c);//输出组成正方形边的字符 C
}
return 0;
}
或
#include
int main(){
//row表示要输出的行数;col表示要输出的列数,即正方形边长 N
int row, col;//定义整型变量row,col
char c;//定义字符型变量c,表示组成正方形边的字符 C
scanf("%d %c", &col, &c);//输入col和c
//根据输出列数col的奇偶性来决定输出的行数row
if((col % 2) == 1){//col为奇数时
//因为col为奇数,则col不能整除2,即col/2不为整数,
//在奇数范围内,无论col为何数,col/2的结果必为x.5的形式,
//则按照正常的算术运算(四舍五入),col/2的结果必向个位进1,所以row=col/2+1
row = col / 2 + 1;
}else{//col为偶数时
//因为col为偶数,则col可以整除2,即col/2为整数,所以row=col/2
row = col / 2;
}
//连续输出col个组成正方形边的字符 C
for(int i = 0; i < col; i++){//当i=col时,则退出循环
printf("%c", c);//输出组成正方形边的字符 C
}
printf("\n");//输出换行
//连续输出(row-2)行有一定规律的字符
for(int i = 2; i < row; i++){//当i=row时,则退出循环
printf("%c", c);//输出组成正方形边的字符 C
//连续输出(col-2)个空格
for(int j = 0; j < (col - 2); j++){//当j=(col-2)时,则退出循环
printf(" ");//输出空格
}
printf("%c\n", c);//输出组成正方形边的字符 C并输出换行
}
//连续输出col个组成正方形边的字符 C
for(int i = 0; i < col; i++){//当i=col时,则退出循环
printf("%c", c);//输出组成正方形边的字符 C
}
return 0;
}
题目描述
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天。
输入
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
输出
每组数据输出一行,即日期差值
样例输入
20130101
20130105
样例输出
5
#include
//定义整型二维数组month,其中数组的一维下标1到12分别表示1月到12月,
//二维下标0表示平年,二维下标1表示闰年。
int month[13][2] = {{0, 0}, {31, 31}, {28, 29}, {31, 31}, {30, 30}, {31, 31},
{30, 30}, {31, 31}, {31, 31}, {30, 30}, {31, 31}, {30, 30}, {31, 31}};
//定义返回值(0或1)为bool类型的函数isLeap(int year),用于判断给定年份year是否为闰年
bool isLeap(int year){
//判断是否为闰年的条件是:year能整除4并且不能整除100,或者year能整除400
return (((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0);
}
int main(){
//time1表示输入的第一个日期;y1表示第一个日期中的年份;
//m1表示第一个日期中的月份;d1表示第一个日期中的日
int time1, y1, m1, d1;//定义整型变量time1,y1,m1,d1
//time2表示输入的第二个日期;y2表示第二个日期中的年份;
//m2表示第二个日期中的月份;d2表示第二个日期中的日
int time2, y2, m2, d2;//定义整型变量time2,y2,m2,d2
//多点测试
while(scanf("%d%d", &time1, &time2) != EOF){//输入time1和time2时,键盘输入Ctrl+Z可退出循环
//默认规定输入的第一个日期time1要小于等于输入的第二个日期time2,即time1<=time2
//判断time1是否小于等于time2,若time1大于time2则交换二者的值
if(time1 > time2){//time1大于time2时
//交换time1和time2的值
int temp = time1;//定义整型变量temp,并将time1的值赋给temp,此时time1相当于为"空"
time1 = time2;//将time2的值赋给time1,此时time2相当于为"空"
time2 = temp;//将temp的值赋给time2,此时便完成了二者值之间的交换
}
//假设正整数n由b个十进制数字组成,对n进行(n/10^m)运算(b>m)相当于
//从左向右取n的(前)(b-m)个十进制数字;对n进行(n%10^m)运算(b>m)相当于
//从右向左取n的(后)m个十进制数字。
y1 = time1 / 10000;//取time1的前4个数字,即第一个日期的年份
m1 = (time1 % 10000) / 100;//取time1的后4个数字的前2个数字,即第一个日期的月份
d1 = time1 % 100;//取time1的后2个数字,即第一个日期的日
y2 = time2 / 10000;//取第二个日期的年份
m2 = (time2 % 10000) / 100;//取第二个日期的月份
d2 = time2 % 100;//取第二个日期的日
int ans = 1;//定义整型变量ans并初始化为1,表示统计的天数
//通过循环逐天累加日期,最终使得time1等于time2,从而得出相差的天数
while((y1 < y2) || (m1 < m2) || (d1 < d2)){//当y1=y2且m1=m2且d1=d2时,则退出循环
d1++;//d1自增1
//判断d1是否等于(当前月份对应天数+1)
if(d1 == (month[m1][isLeap(y1)] + 1)){//d1等于(当前月份对应天数+1)时
m1++;//当d1等于(当前月份对应天数+1)时,如32,月份m1自增1,相当于下个月
d1 = 1;//当d1等于(当前月份对应天数+1)时,d1重置为1,相当于下个月的1号
}
//判断月份m1是否等于13
if(m1 == 13){//月份m1等于13时
y1++;//当月份m1等于13时,年份y1自增1,相当于下一年
m1 = 1;//当月份m1等于13时,月份m1重置为1,相当于下一年的1月
}
ans++;//天数自增1
}
printf("%d\n", ans);//输出统计完成后的天数
}
return 0;
}
或
#include
int month[13][2] = {{0, 0}, {31, 31}, {28, 29}, {31, 31}, {30, 30}, {31, 31},
{30, 30}, {31, 31}, {31, 31}, {30, 30}, {31, 31}, {30, 30}, {31, 31}};
bool isLeap(int year){
return (((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0);
}
int main(){
int time1, y1, m1, d1;
int time2, y2, m2, d2;
while(scanf("%d%d", &time1, &time2) != EOF){
if(time1 > time2){
int temp = time1;
time1 = time2;
time2 = temp;
}
y1 = time1 / 10000;
m1 = (time1 % 10000) / 100;
d1 = time1 % 100;
y2 = time2 / 10000;
m2 = (time2 % 10000) / 100;
d2 = time2 % 100;
int ans = 1;
//此处是与上一个程序相比唯一多出的部分,该程序的其他部分与上一个程序均一致。
//通过循环逐年累加年份,最终使得y1=(y2-1);
//累加天数时根据平年或闰年选择在天数上累加365或366;
//通过添加这一部分可加快程序的运行速度,该程序的运行速度要快于上一个程序
while(y1 < (y2 - 1)){//当y1=(y2-1)时,则退出循环
y1++;//年份y1自增1
//判断年份y1是否为闰年
if(isLeap(y1)){//y1为闰年时
ans += 366;//在天数上累加366
}else{//y1为平年时
ans += 365;//在天数上累加365
}
}
//进入下面的循环之前,此时y1=(y2-1)
while((y1 < y2) || (m1 < m2) || (d1 < d2)){
d1++;
if(d1 == (month[m1][isLeap(y1)] + 1)){
m1++;
d1 = 1;
}
if(m1 == 13){
y1++;
m1 = 1;
}
ans++;
}
printf("%d\n", ans);
}
return 0;
}
#include
int main(){
//y表示进制转换后得到的十进制数
int y = 0;//定义整型变量y并将其初始化为0
//在循环中product与P累乘可得到:1,P^1,P^2,P^3,…
int product = 1;//定义整型变量product并将其初始化为1
//P表示P进制的基数,其中P的范围为1
int P;//定义整型变量P
//x表示要转换成十进制的P进制数,假设x为a1a2a3…an
int x;//定义整型变量x
//多点测试;输入时,键盘输入Ctrl+Z可退出循环
while(scanf("%d %d", &P, &x) != EOF){//输入P进制的基数和要转换的P进制数
//通过循环实现根据公式:y=a1*P^(n-1)+a2*P^(n-2)+…+an*P^0来计算转换后的十进制数
while(x != 0){//x=0时,则退出循环
//x%10表示取当前循环下x的后一位数字,即取当前循环下x的个位数,如an
//(x%10)*product表示公式中的单个累加项,如an*P^0
y += (x % 10) * product;//等价写法:y = y + (x % 10) * product
//假设当前循环下x的位数为b位,则x/10表示取当前循环下x的前(b-1)位数字,
//或者说去掉当前循环下x的个位数
x /= 10;//等价写法:x = x / 10
//product表示P进制基数的幂,如P^(n-1)
product *= P;//等价写法:product = product * P
}
printf("%d\n", y);//输出转换后的十进制数
//测试完每组数据之后,需要将y和product重新初始化
y = 0;
product = 1;
}
return 0;
}
输入:
2 110
输出:
6
#include
int main(){ //数组z用于存放Q进制数z的每一位 int z[40];//定义整型数组z,其数组长度为40 //num表示转换后Q进制数z的位数 int num = 0;//定义整型变量num并将其初始化为0 int y;//定义整型变量y,表示转换成Q进制数的十进制数y int Q;//定义整型变量Q,表示Q进制的基数,其中Q的范围为1 //多点测试;输入时,键盘输入Ctrl+Z可退出循环 while(scanf("%d %d", &Q, &y) != EOF){//输入Q进制的基数和换成Q进制数的十进制数y //通过循环实现利用"除基取余法"来计算转换后的Q进制数 do{ //取出当前循环下y/Q的余数并将其赋给z[num++], //其中num++表示先使用num的值,然后再将num自增1,可以说余数赋给了z[num] z[num++] = y % Q; //取出当前循环下y/Q的商并将其赋给y,作为下一轮循环中的被除数 y /= Q;//等价写法:y = y / Q }while(y != 0);//y=0时,则执行一次循环体后退出循环 //循环计算完后,数组z从高位z[num-1]到低位z[0]便为Q进制数z for(int i = (num-1); i >= 0; i--){//i<0时,退出循环 printf("%d", z[i]);//循环输出Q进制数z的每一位数 } printf("\n");//输出换行 //测试完每组数据后需要将num重新初始化 num = 0; } return 0; }输入: 8 64 输出: 100
3.【PAT B1022】D进制的A+B
输入两个非负 10 进制整数 A 和 B (≤2^30−1),输出 A+B 的 D (1<D≤10)进制数。 输入格式: 输入在一行中依次给出 3 个整数 A、B 和 D。 输出格式: 输出 A+B 的 D 进制数。 输入样例: 123 456 8 输出样例: 1103
#include
int main(){ //a表示输入的十进制数A;b表示输入的十进制数B; //d表示D进制的基数 int a, b, d;//定义整型变量a,b,d scanf("%d %d %d", &a, &b, &d);//输入a,b,d //sum表示十进制数A与十进制数B的和 int sum = a + b;//定义整型变量sum并将a与b的和赋给sum //数组z用于存放D进制数的每一位 //因为输入的十进制整数A和B的范围为(<=2^30-1),所以数组z的长度也可以为31。 int z[40];//定义整型数组z,其数组长度为40//ans[31] //num表示转换后D进制数的位数 int num = 0;//定义整型变量num并将其初始化为0 //通过循环实现利用"除基取余法"来计算转换后的D进制数 do{ z[num++] = sum % d;//取出当前循环下sum/d的余数并将其赋给z[num++]//ans[31] sum /= d;//取出当前循环下sum/d的商并将其赋给sum,作为下一轮循环中的被除数 }while(sum != 0);//sum=0时,则执行一次循环体后退出循环 //循环计算完后,数组z从高位z[num-1]到低位z[0]便为D进制数 for(int i = (num - 1); i >= 0; i--){//i<0时,退出循环 printf("%d", z[i]);//循环输出D进制数的每一位数//ans[31] } printf("\n");//输出换行 return 0; } 3.6字符串处理
1.【codeup 5901】回文串
题目描述 读入一串字符,判断是否是回文串。“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等 就是回文串。 输入 一行字符串,长度不超过255。 输出 如果是回文串,输出“YES”,否则输出“NO”。 样例输入 12321 样例输出 YES
#include
#include //maxn表示字符型数组str的最大长度 //因为输入的字符串长度不超过255,所以maxn可以为256 const int maxn = 256;//定义整型常量maxn并将其初始化为256 //定义返回值(true或false)为bool类型的函数judge(char str[]), //用于判断给定的"字符串"str是否为"回文串" bool judge(char str[]){ //调用strlen()函数来获取"字符串"str的长度并将其赋给len int len = strlen(str);//定义整型变量len,表示"字符串"str的长度 //通过循环依次遍历字符型数组str中的前(len/2)个元素, //来判断整个字符型数组str中所有对称位置的元素是否相等。 //当len为偶数时,则(len/2)必为整数,即len的一半,所以可取得相互对称元素个数的一半; //当len为奇数时,因为len为整型变量,所以(len/2)的结果会舍去小数部分从而取整,其要 //小于len的一半,由于str中位于中间的那个元素不存在对称元素,所以恰好可取得相互对称 //元素个数的一半。综上所述,无论len为何数,(len/2)总为相互对称元素个数的一半。 for(int i = 0; i < (len / 2); i++){//i=(len/2)时,则退出循环 //判断字符型数组str中对称位置的元素是否相等。 //对于字符型数组str中下标为i的元素,其对称位置的元素 //所对应的字符型数组str的下标为len-1-i if(str[i] != str[len-1-i]){//对称位置元素不相等时 return false;//返回false } } return true;//返回true } int main(){ char str[maxn];//定义字符型数组str,其最大长度为maxn,用于存储输入的"字符串"str scanf("%s", str);//输入"字符串"str //调用自定义的judge()函数,来判断str是否为"回文串",并将其返回值赋给flag bool flag = judge(str);//定义bool类型变量flag //根据flag的值来判断输出YES或NO if(flag == true){//flag为true时 printf("YES\n");//输出YES和换行 }else{//flag为false时 printf("NO\n");//输出NO和换行 } return 0; } 2.【PAT B1009】说反话
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其 中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的 空格。 输出格式: 每个测试用例的输出占一行,输出倒序后的句子。 输入样例: Hello World Here I Come 输出样例: Come I Here World Hello
#include
#include int main(){ //num表示输入单词的个数 int num = 0;//定义整型变量num并将其初始化为0 //输入的字符串总长度不超过80,且字符串由若干单词和若干空格组成, //则输入的单词个数和单个的单词长度均要小于80,所以数组ans的一维 //长度可以为90,二维长度可以为90 char ans[90][90];//定义二维字符型数组ans,用于存储输入的单词 //字符型数组使用%s读入的时候以空格跟换行为读入结束的标志。 //假设输入为:"hello world\n^Z\n"时('\n'表示键盘输入"Enter";'^Z'表示键盘输入"Ctrl+Z"), //scanf()函数读取"world"前的空格后便结束读入并返回1,此时ans[0]中便存储了"hello\0", //由于1!=EOF,所以执行循环体num++后再从字符串中的"w"开始读取,当读取第一个"\n"后便 //结束读入并返回1,此时ans[1]中便存储了"world\0",由于1!=EOF,所以执行循环体num++后再 //从字符串中的'^Z'开始读取,当读取第二个'\n'后便结束读入并返回EOF,此时EOF=EOF,所以 //退出循环不再执行循环体。 while(scanf("%s", ans[num]) != EOF){//输入时,键盘输入Ctrl+Z可退出循环 num++;//输入的单词个数自增1 } //数组ans中是以输入正序的形式来存储单词,则输出时需要以数组元素的倒序形式进行输出, //即将i的初始值置为(num-1) for(int i = (num - 1); i >= 0; i--){//i<0时,退出循环 printf("%s", ans[i]);//输出单个的单词 //在输出的每个单词后输出一个空格 if(i > 0){//i=0时,不输出空格,即避免在输出的最后一个单词后输出空格 printf(" ");//输出空格 } } return 0; } 或
#include
#include int main(){ //因为输入的字符串总长度不超过80,所以数组str的长度可以为90 char str[90];//定义字符型数组str,用于存储输入的"字符串" //gets()函数可以读入空格,其识别换行符"\n"作为输入结束 gets(str);//输入字符串 //调用strlen()函数来获取"字符串"str的长度并将其赋值给len int len = strlen(str);//定义整型变量len //r表示输入单词的个数;h表示组成单个单词的字符个数 int r = 0, h = 0;//定义整型变量r,h并将二者均初始化为0 char ans[90][90];//定义二维字符型数组ans,用于存储输入的单词 int i, j;//定义整型变量i,j,i和j均表示下面循环中数组的下标 //通过循环依次遍历数组str中的每个元素,以空格为分隔,将输入的 //单词存储至数组ans中 for(i = 0; i < len; i++){//i=len时,则退出循环 //判断字符是否为空格 if(str[i] != ' '){//str[i]不为空格时 //将输入的单个单词存储在数组ans的不同维度中,如ans[0] ans[r][h++] = str[i]; }else{//str[i]为空格时 //scanf()函数和gets()函数均会自动地在读取的字符串后加上空字符'\0' ans[r][h] = '\0';//在每一维度中的单词后加上'\0',用于后续单词的输出 //printf()函数和puts()函数是通过识别'\0'作为字符串的结尾来输出的 r++;//输入的单词个数自增1,即数组ans的维度自增1,用于存储下一个单词 h = 0;//将h重置为0,用于统计下一个组成单词的字符个数 } } //以倒序的形式输出数组ans中存储的单词 for(j = r; j >= 0; j--){//j<0时,则退出循环 printf("%s", ans[j]);//输出单个的单词 //在输出的每个单词后输出一个空格 if(j > 0){//j=0时,不输出空格,即避免在输出的最后一个单词后输出空格 printf(" ");//输出空格 } } return 0; } 参考资料如下:
[1] 胡凡,曾磊.算法笔记[M].北京:机械工业出版社,2022:85-98.
[2] codeup网址:http://codeup.hustoj.com
[3] PAT网址:https://www.patest.cn/practice