【C语言每日题解】三题:回文检查、刘备 关羽 张飞三人过年放鞭炮、犹太人死亡游戏(难度up,推荐⭐✨)

本文主要是介绍【C语言每日题解】三题:回文检查、刘备 关羽 张飞三人过年放鞭炮、犹太人死亡游戏(难度up,推荐⭐✨),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 🥰欢迎关注 轻松拿捏C语言系列,来和 小哇 一起进步!✊

🌈感谢大家的阅读、点赞、收藏和关注

🥰希望大家喜欢我本次的讲解

🌟非常推荐最后一道题 🌹 犹太人死亡游戏,建议观看


🌙目录

💕题目一:回文检查

🎉题目二:刘备、关羽、张飞过年放鞭炮

🌹题目三: 犹太人死亡游戏

        所以我们要做的就是如何让数组中最后一个元素过了之后又来到开头的元素。

其次,该题还有一个要点:如何将总人数n储存进数组?因为n是变化的,由用户输入

        1.变长数组

        2.动态内存分配


 

💕题目一:回文检查

根据题目要求,我们可以知道要输入一个完整的英文句子,其中包括空格

        这里我们就要注意了,在scanf 中使用%s来输入字符串时,它会从第一个非空白字符开始读取,直到遇到空白字符就停止读取。也就是说我们这里不能使用scanf来直接读取含有空白的字符串

      gets()和 fgets()函数可以读取含有空白的字符串

 用法://gets()

            char arr[100];  
            gets(arr); // 读取直到换行符或EOF,但不检查缓冲区大小

            //fgets()

            char arr[100];

            fgets(arr, sizeof(arr), stdin); // 读取最多 sizeof(arr)-1 个字符,或直到换行符或EOF

                //stdin为标准输入

        另外,gets没有fgets安全,因为前者不检查缓冲区大小,可能导致缓冲区溢出

我们知道了如何输入一个包含空格的英文句子后,按题目要求 不考虑空格和标点符号,所以接着我们就要想办法除去空格和标点。

        这里我想到的是可以利用ASCII码表,根据不同字符的ASCII码值的不同,我们将每一个字符进行条件判断 如果它在英文大写字母A~Z之间或英文小写字母 a~z之间,那么就留下

        否则就不是字母即为空格或其他符号,那么就不要。

// 函数:检查字符是否为字母  
int is_alpha(char c) {return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
// 函数:移除字符串中的空格和标点符号,并返回处理后的字符串长度  
int remove(char* src, char* dest) {int i, j = 0;for (i = 0; src[i] != '\0'; i++) {if (is_alpha(src[i])) {dest[j++] = src[i]; }}dest[j] = '\0'; // 添加字符串终止符  return j;
}

我们拿到只有字母的字符串后,就可以把它逆置,然后再和逆置之前的去比较,如果每个字符都相同,则是;有不同,则不是。

当然这里也可以不用逆置,让字符串首尾元素比较也可以判断。

// 函数:检查两个字符串(已处理,忽略空格和标点符号)是否为回文
// //方法二,字符数组首尾元素对比检查  
int check2(char* str1, char* str2, int len) 
{int i;for (i = 0; i < len / 2; i++) {if (str1[i] != str2[len - i - 1]) {return 0; // 不是回文  }}return 1; // 是回文  
}
// 方法一  将逆置和原来的字符数组对比
int check1(char* str1, char* str2, int len)
{int i;for (i = 0; i < len; i++){if (str1[i] != str2[i])return 0;}return 1;
}

现在我们已经解决了这一道题了,来看一下完整代码

      代码实现       

// 函数:检查字符是否为字母  
int is_alpha(char c) {return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
// 函数:移除字符串中的空格和标点符号,并返回处理后的字符串长度  
int remove(char* src, char* dest) {int i, j = 0;for (i = 0; src[i] != '\0'; i++) {if (is_alpha(src[i])) {dest[j++] = src[i]; }}dest[j] = '\0'; // 添加字符串终止符  return j;
}
// 函数:检查两个字符串(已处理,忽略空格和标点符号)是否为回文
// //方法二,字符数组首尾元素对比检查  
int check2(char* str1, char* str2, int len) 
{int i;for (i = 0; i < len / 2; i++) {if (str1[i] != str2[len - i - 1]) {return 0; // 不是回文  }}return 1; // 是回文  
}
// 方法一  将逆置和原来的字符数组对比
int check1(char* str1, char* str2, int len)
{int i;for (i = 0; i < len; i++){if (str1[i] != str2[i])return 0;}return 1;
}
int main()
{char a[20];char b[20];fgets(a, sizeof(a), stdin);int len = remove(a, b); // 检查处理后的句子和反转后的句子是否相同(忽略大小写)// 方法一 , 将逆置和原来的字符数组对比// 反转处理后的句子并检查是否为回文  char temp[20];int l = len - 1;for (int i = 0; i < len; i++){temp[i] = b[l--];}if (check1(temp, b, len)) {printf("YES\n");}else {printf("NO\n");}//检查处理后的句子和反转后的句子是否相同(忽略大小写)  //方法二,字符数组首尾元素对比检查if (check2(b, b, len)) {printf("YES\n");}else {printf("NO\n");}return 0;
}

🎉题目二:刘备、关羽、张飞过年放鞭炮

根据规律可以发现有n个鞭炮时,刘备放炮的时间点在n,关羽的在2n-1,张飞的在3n-2。

         同样的鞭炮数量,张飞最后放完,所以他决定一共花了多少时间

现在来解决一共能听到多少声的问题。

        我们可以把他们每个人从放第1个鞭炮到放第n个鞭炮的时间点分别装进三个数组,比如 刘备的就是 {1,2,3,……n}

        接着数出一共有多少个时间点,当然相同的时间点只计算一次,比如n=1时,他们放炮时间点都为1,三个1一起响,所以只计一次;n=2时,时间点分别在2、3、4,不在同一个时间点,所以响三次,都要计数。

        数出有多少个时间点(相同点计一次),我们就知道一共有多少次响声。

      代码实现         

#include<stdio.h>void Func1(int liu[], int num)//存储刘备放炮时间点
{int i = 0;for (i; i <num; i++){liu[i] = i+1;}
}
void Func2(int guan[], int num)//存储关羽放炮时间点
{int i = 0;for (i; i < num; i++){guan[i] = 2*i+1;}
}
void Func3(int zhang[], int num)//存储张飞放炮时间点
{int i = 0;for (i; i < num; i++){zhang[i] = 3*i + 1;}
}
int sound(int liu[], int guan[], int zhang[], int n)
{int i;int temp = n;//将刘关二人放炮时间点放在一起,重复的只计一次for (i = 0; i < n; i++){int j = 0;while(j<temp){if (guan[i] == liu[j])break;elsej++;}if (guan[i] != liu[j]){liu[temp] = guan[i];temp++;}}//将三人放炮时间点放在一起,重复的只计一次for (i = 0; i < n; i++){int j = 0;while (j < temp){if (zhang[i] == liu[j])break;elsej++;}if (zhang[i] != liu[j]){liu[temp] = zhang[i];temp++;}}//三人响声次数return temp;
}
//刘备、关羽、张飞过年放炮问题
int main()
{int n = 0;scanf("%d", &n);//输入鞭炮数量int liu[100] = { 0 };int guan[100] = { 0 };int zhang[100] = { 0 };Func1(liu,n);Func2(guan,n);Func3(zhang,n);int count = sound(liu,guan,zhang,n);//响声printf("time = %d\n", 3 * n - 2);//时间printf("count = %d", count);return 0;
}

🌹题目三: 犹太人死亡游戏

​ 

这道题的思路和题目描述一样,定义一个长度为n的数组,数组元素一开始都为0,从第一个开始报数,报到m的人死亡,其对应元素赋值为1。

         我们需要注意的是如何让这个数组中活着的人能够循环报数,即让这些人像图中一样能够“围起来”   最后一个人报完数让下一个人接着报数。  

        所以我们要做的就是如何让数组中最后一个元素过了之后又来到开头的元素。

        在这里我学到一个非常巧妙的写法 

//举例(并非该题完整代码)

int arr [5] ={1,2,3,4,5};//假设n = 5

int m = 3;//假设 m = 3

int i = 0;

int count = 0;//计数

while(条件)

{        count++; 

        if(count = = m)    

        {

                arr[i] = 0;

                count = 0;

        }

          i = (i + 1) % 5; // 移动到下一个位置      

}

        我们给当前数组下标 i 赋值i +1 虽然也能到下一个元素arr[i+1],但是一直+1会超过数组arr的限度,导致缓冲区溢出 。但是我们采用 i = (i + 1) % 5 的写法 让i+1后 模上数组最大长度5,这样最后一个元素过了之后又能够来到开头的元素。

其次,该题还有一个要点:如何将总人数n储存进数组?因为n是变化的,由用户输入

        这里 简单 讲两个方法:1.变长数组

                                              2.动态内存分配

        1.变长数组

int n;

scanf("%d",&n);

int arr[n];

        但是在Visual Studio中 ,变长数组是不能使用的(😑我在牛客网答题遇到过)

        所以这里我们使用第二种方法

        2.动态内存分配

        使用要包含头文件 <stdlib.h>

        从堆区分配内存,使用完后再收回存储空间

        主要函数malloc、calloc、free

        这里我们只使用malloc和free

int n;

scanf("%d",&n);

int* arr = (int*)malloc(n*sizeof(int));//现在arr可以存储n个int类型的数字

if (ptr == NULL) {  
    ……
}
// 处理内存分配失败的情况

……//使用arr

 //使用完释放内存块

 free(arr);

🆗回归题目,先来再简述一遍题干:

        有n个人一开始都为0,从第一个人开始报数(从1开始喊),谁报到数字m就死亡,然后他的0变成1 。下一个人又接着从1开始报数,谁报到数字m就死亡,他的0也变成1。一直持续,直到只剩两个活人,其他人都死了,即n个人里只有两个0,其余都是1,游戏结束🤣

        所以我们这个循环报数的条件可以是   活人数量>2,当最后只有两个活人时就结束循环。

        在循环里,即游戏进行中 ,大家都在报数时, 只有活人才报数,死人不报数(诈尸也不行哈哈)。每次报数从1~m,喊到m的人死,活人数量就减减。下一个活人报数就又从1开始喊。

        游戏结束后我们就可以开始找两个幸存者的编号,题上说他们的编号就是 下标+1,只需要遍历游戏结束后的数组去找0在哪里,我们就可以知道幸存者编号

      代码实现       

#include<stdio.h>
#include<stdlib.h>
void game(int *arr,int mm,int nn )
{int count = 0;//计数int i = 0;//下标int survivors = nn;//活人(幸存者)while ( survivors > 2)//不满足条件时,游戏结束{if (arr[i] == 0) // 如果当前人还是活人(死了变成1){ count++; //活人就要报数,给我开始喊  if (count == mm) // 报数到mm时,0变1,活人死去{   arr[i] = 1; // 0-->1,人死count = 0;//后面的人重新报数  survivors--;//活人少一个}}i = (i + 1) % nn; // 下标移动到下一个位置,该下一个哥们 }//出了循环 游戏结束  找两个0的位置int j;int temp[2];//装两个0的编号int k = 0;for (j = 0; j < nn; j++){if (arr[j] == 0)//找到0{temp[k] = j+1;//下标+1 就是题目要求的 编号k++;}if (k == 2)//两个0找到后,跳出循环break;}printf("Josephus 和他的朋友的位置:%d %d", temp[0], temp[1]);
}
//犹太人死亡游戏
int main()
{int n, m;printf("输入总人数n(2<n<1000):");scanf("%d", &n);printf("输入报数值(2<m<=n):");scanf("%d", &m);//动态分配内存int* arr = (int*)malloc(n * sizeof(int));if (arr == NULL) { // 检查malloc是否成功  printf("动态内存分配失败\n");}int h;for (h = 0; h < n; h++)arr[h] = 0;//活人一开始都是0game(arr,m,n);//调用函数,进入游戏//释放内存块free(arr);return 0;
}

​🎉🎉本次的内容结束啦,希望大家喜欢 能够看懂

😘💕希望大家能够三连支持,你们的鼓励是我前进的动力

🌹🌹谢谢观看!

这篇关于【C语言每日题解】三题:回文检查、刘备 关羽 张飞三人过年放鞭炮、犹太人死亡游戏(难度up,推荐⭐✨)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/991486

相关文章

C语言中联合体union的使用

本文编辑整理自: http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=179471 一、前言 “联合体”(union)与“结构体”(struct)有一些相似之处。但两者有本质上的不同。在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量

大语言模型(LLMs)能够进行推理和规划吗?

大语言模型(LLMs),基本上是经过强化训练的 n-gram 模型,它们在网络规模的语言语料库(实际上,可以说是我们文明的知识库)上进行了训练,展现出了一种超乎预期的语言行为,引发了我们的广泛关注。从训练和操作的角度来看,LLMs 可以被认为是一种巨大的、非真实的记忆库,相当于为我们所有人提供了一个外部的系统 1(见图 1)。然而,它们表面上的多功能性让许多研究者好奇,这些模型是否也能在通常需要系

LeetCode11. 盛最多水的容器题解

LeetCode11. 盛最多水的容器题解 题目链接: https://leetcode.cn/problems/container-with-most-water 示例 思路 暴力解法 定住一个柱子不动,然后用其他柱子与其围住面积,取最大值。 代码如下: public int maxArea1(int[] height) {int n = height.length;int

人工和AI大语言模型成本对比 ai语音模型

这里既有AI,又有生活大道理,无数渺小的思考填满了一生。 上一专题搭建了一套GMM-HMM系统,来识别连续0123456789的英文语音。 但若不是仅针对数字,而是所有普通词汇,可能达到十几万个词,解码过程将非常复杂,识别结果组合太多,识别结果不会理想。因此只有声学模型是完全不够的,需要引入语言模型来约束识别结果。让“今天天气很好”的概率高于“今天天汽很好”的概率,得到声学模型概率高,又符合表达

比较学习难度:Adobe Illustrator、Photoshop和新兴在线设计平台

从入门设计开始,几乎没有人不知道 Adobe 公司两大设计软件:Adobe Illustrator和 Photoshop。虽然AI和PS很有名,有一定设计经验的设计师可以在早期探索和使用后大致了解AI和PS的区别,但似乎很少有人会系统地比较AI和PS。目前,设计软件功能多样,轻量级和网页设计软件已成为许多设计师的需求。对于初学者来说,一篇有针对性的AI和PS比较总结文章具有非常重要的指导意义。毕竟

高仿精仿愤怒的小鸟android版游戏源码

这是一款很完美的高仿精仿愤怒的小鸟android版游戏源码,大家可以研究一下吧、 为了报复偷走鸟蛋的肥猪们,鸟儿以自己的身体为武器,仿佛炮弹一样去攻击肥猪们的堡垒。游戏是十分卡通的2D画面,看着愤怒的红色小鸟,奋不顾身的往绿色的肥猪的堡垒砸去,那种奇妙的感觉还真是令人感到很欢乐。而游戏的配乐同样充满了欢乐的感觉,轻松的节奏,欢快的风格。 源码下载

C语言 将“China”译成密码

将“China”译成密码,密码规律是:用原来的字母后面的第4个字母代替原来的字母。例如,字母“A”后面的第4个字母是“E”,用“E”代替“A”。因此,“China”应译为“Glmre”。编译程序用付赋初值的方法使c1,c2,c3,c4,c5这五个变量的值分别为“C”,“h”,“i”,“n”,“a”,经过运算,使c1,c2,c3,c4,c5分别变成“G”,“l”,“m”,“r”,“e”。分别用put

C语言入门系列:探秘二级指针与多级指针的奇妙世界

文章目录 一,指针的回忆杀1,指针的概念2,指针的声明和赋值3,指针的使用3.1 直接给指针变量赋值3.2 通过*运算符读写指针指向的内存3.2.1 读3.2.2 写 二,二级指针详解1,定义2,示例说明3,二级指针与一级指针、普通变量的关系3.1,与一级指针的关系3.2,与普通变量的关系,示例说明 4,二级指针的常见用途5,二级指针扩展到多级指针 小结 C语言的学习之旅中,二级

LeetCode--234 回文链表

题目 请判断一个链表是否为回文链表。 示例 示例 1:输入: 1->2输出: false示例 2:输入: 1->2->2->1输出: true /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val

LeetCode--214 最短回文串

题目 给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。 示例 示例 1:输入: "aacecaaa"输出: "aaacecaaa"示例 2:输入: "abcd"输出: "dcbabcd" 思路: 我们需要添加多少个字符与给定字符串的前缀子串回文的长度有关. 也就是说去掉其前缀的回文子串,我们只需要补充剩下的子串的逆序