目录
首先我们先来看一下题目具体要求

再来看一下我们所需要的效果

这里呢,博主给出两种思路,一种是先将整个字符串逆序,再将单个单词逆序;另一种是先将单个单词厉旭,再将整个字符串逆序
- 第一种
- I like beijing.
- .gnijieb ekil I
- beijing. like i
- 第二种
- I ekil .gnijieb
- beijing. like I
这里博主采用的是将整个字符串逆序,再将单个单词逆序(采用的是指针,若有宝子不懂得,可以看看博主以前得文章)因为需要逆序整个字符串和每个单词,所以博主在这儿将逆序这个功能单独拿出来,实现函数如下
- void jiaohuan(char* p1, char* p2)
- {
- while (p1 < p2)//退出循环的条件
- {
- char tmp = *p1;
- *p1 = *p2;
- *p2 = tmp;
- p1++;
- p2--;
- }
- }
我们有了这个函数后,后面需要逆序时我们就只需要调用就好了
当我们逆序了整个字符串后,逆序每个单词成了我们的难点,首先我们得知道,单词与单词用什么来判断,如何判断结束:单词与单词间我们用空格,结束我们们用‘\0'来判断
这里博主引入两个指针
- char* start = arr;
- char* cur = arr;
start不用动,cur遍历整个数组,原理如下

其实到这儿我们基本多思考一下就大概可以想到解题代码了,如果没有思路,就浅看一下博主写的吧
- while (*cur)
- {
- while (*cur != ' '&&*cur!='\0')//判断跳出循环的条件
- {
- cur++;
- }
- jiaohuan(start, cur - 1);//逆序每一单词
- start = cur + 1;//cur当前指的为空格,所一下一单词得开头需要加一
- if (*cur == ' ')//当有空格时,由于cur此时指得是空格,所以遍历时需要向后进一位
- cur++; //若没有空格,说明字符串已经遍历完成,不可再加一,否则会造成越界
- }
图解如下

主要功能已完成,我们便可以写出完整代码了,代码如下
- #include <stdio.h>
-
- void jiaohuan(char* p1, char* p2)
- {
- while (p1 < p2)
- {
- char tmp = *p1;
- *p1 = *p2;
- *p2 = tmp;
- p1++;
- p2--;
- }
- }
-
- int main()
- {
- char arr[101];
- gets(arr);
- int len = strlen(arr);
- jiaohuan(arr,arr+len-1);
- char* start = arr;
- char* cur = arr;
- while (*cur)
- {
- while (*cur != ' '&&*cur!='\0')//判断跳出循环的条件
- {
- cur++;
- }
- jiaohuan(start, cur - 1);
- start = cur + 1;
- if (*cur == ' ')
- cur++;
- }
- printf("%s", arr);
- return 0;
- }
题目具体要求如下

考虑到一共五个人,直接模拟推理有些太难,计算机最擅长的遍历此时就会派上用场,将每个人从第1到第5来一遍,则一共会产生5^5种可能性,这个只需要一个5层循环即可搞定。

其实这道题最难的是,如何判断选手那句话为真,其实我们把上述问题给简化一下

我们呢所需要做的只是,对每一位选手说的话只信一半,然后把最后得出名次进行汇总,符合我们的条件就输出
我们发现每一位选手都说了自己与另一名选手的成绩 ,那么我们是否可以把我们循环得到的数字与选手所说的进行判断呢,代码如下
- int shuohuang(int m, int n,int x,int y)
- //m,n为循环得到选手名词,x,y为选手自己所说名次
- {
- if ((m == x && n != y) || (m != x && n == y))
- return 1;
- else return 0;
- }
对每个选手判断后,如果返回值都为1,那么就是我们想要的名次了吗?
这里注意,并不是,博主已经吃过亏了,希望各位宝子可以避免。因为由于循环的原因会导致一些不期望出现的结果出现,因为我并没有查重,所以会出现两个人抢名次的情况,也就是两个人或者更多的人名次相同的情况,例如两个第二,三个第三这样的,所以即使满足了条件,也要查看一下五个人的名次是否重复,这个交给一个函数来执行
- int panduan(int a, int b, int c, int d, int e)
- {
- if (shuohuang(a, b, 3, 2) && shuohuang(b, e, 2, 4) && shuohuang(c, d, 1, 2) && shuohuang(d, c, 3, 5) && shuohuang(e, a, 4, 1) && (a != b && a != c && a != d && a != e && b != c && b != d && b != e && c != d && c != e && d != e))
- return 1;
- else return 0;
- }
到这里我们就完成了一大半了,那么还有一个问题,当你遍历到正确答案,该怎么跳出循环呢,看看博主怎么做的吧
- for (a = 1; a <= 5; a++)
- {
- for (b = 1; b <= 5; b++)
- {
- for (c = 1; c <= 5; c++)
- {
- for (d = 1; d <= 5; d++)
- {
- for (e = 1; e <= 5; e++)
- {
- if (panduan(a, b, c, d, e))//判断成功跳出循环
- {
- ret = 1;
- break;//一个break只跳出一个循环
- }
- }
- if (ret == 1)
- break;
- }
- if (ret == 1)
- break;
- }
- if (ret == 1)
- break;
- }
- if (ret == 1)
- break;
- }
由于一个break只跳出一个循环,所以这里博主用了多个break;
完整代码如下
- int shuohuang(int m, int n,int x,int y)
- {
- if ((m == x && n != y) || (m != x && n == y))
- return 1;
- else return 0;
- }
-
- int panduan(int a, int b, int c, int d, int e)
- {
- if (shuohuang(a, b, 3, 2) && shuohuang(b, e, 2, 4) && shuohuang(c, d, 1, 2) && shuohuang(d, c, 3, 5) && shuohuang(e, a, 4, 1) && (a != b && a != c && a != d && a != e && b != c && b != d && b != e && c != d && c != e && d != e))
- return 1;
- else return 0;
- }
-
- int main()
- {
- int a = 0;
- int b = 0;
- int c = 0;
- int d = 0;
- int e = 0;
- int ret = 0;
- for (a = 1; a <= 5; a++)
- {
- for (b = 1; b <= 5; b++)
- {
- for (c = 1; c <= 5; c++)
- {
- for (d = 1; d <= 5; d++)
- {
- for (e = 1; e <= 5; e++)
- {
- if (panduan(a, b, c, d, e))
- {
- ret = 1;
- break;
- }
- }
- if (ret == 1)
- break;
- }
- if (ret == 1)
- break;
- }
- if (ret == 1)
- break;
- }
- if (ret == 1)
- break;
- }
- printf("A:%d\nB;%d\nC;%d\nD;%d\nE;%d\n", a, b, c, d, e);
- return 0;
- }
题目具体要求如下

本题代码简单,但是呢思维巧妙,相信各位宝子看完代码就可以理解了
- #include<stdio.h>
- int main()
- {
- int killer = 0;
- //分别假设凶手是a,b,c,d,看谁是凶手时满足3个人说了真话,一个人说了假话
- for (killer = 'a'; killer <= 'd'; killer++)
- {
- if ((killer != 'a') + (killer == 'c') + (killer == 'd') + (killer != 'd') == 3)
- printf("凶手是:%c", killer);
- }//只需要一个个遍历,满足这四个人中三个人的条件即可判断出来
- return 0;
- }
题目要求为

题目要求了解呢后,我们来了解一下什么叫杨辉三角吧
杨辉三角(也称帕斯卡三角)相信很多人都不陌生,它是一个无限对称的数字金字塔,从顶部的单个1开始,下面一行中的每个数字都是上面两个数字的和。
杨辉三角,是二项式系数在三角形中的一种几何排列,在中国南宋数学家杨辉1261年所著的《详解九章算法》一书中出现。在欧洲,帕斯卡(1623—-1662)在1654年发现这一规律,所以这个表又叫做帕斯卡三角形。帕斯卡的发现比杨辉要迟393年,比贾宪迟600年。
其实这道题主要是找到规律就好做了,一起来看看博主的代码吧
- #include <stdio.h>
- int main()
- {
- int n = 0;
- int i = 0;
- int arr[1000] = { 0 };
- scanf("%d", &n);
- for (i = 1; i < n; i++)
- {
- arr[0] = 1;
- int j = i-1;
- int x = 0;
- for (; j >0; j--)
- {
- arr[j] = arr[j - 1] + arr[j];
- }
- for (x = 0; x <i; x++)
- {
- printf("%d ", arr[x]);
- }
- printf("\n");
- }
- return 0;
- }
画图解释如下

- void yangHuiTriangle(int n)
- {
- int data[30][30] = { 1 }; //第一行直接填好,播下种子
-
- int i, j;
-
- for (i = 1; i < n; i++) //从第二行开始填
- {
- data[i][0] = 1; //每行的第一列都没有区别,直接给1,保证不会越界。
- for (j = 1; j <= i; j++) //从第二列开始填
- {
- data[i][j] = data[i - 1][j] + data[i - 1][j - 1]; //递推方程
- }
- }
-
- for (i = 0; i < n; i++) //填完打印
- {
- for (j = 0; j <= i; j++)
- {
- printf("%d ", data[i][j]);
- }
- putchar('\n');
- }
- }
以上是博主在学习中遇到的难题,在此分享做题经验,对于这些题目有其他见解的友友,欢迎评论去留言探讨。