提示:自己做的可能复杂,请各位大佬指正

文章目录

  • 一、题目
  • 二、思路
  • 三、实现的过程
    • 1.主函数
    • 2.初始感冒蚂蚁的设置
    • 3.感冒蚂蚁的判定
  • 总结

一、题目

长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒,并列出哪几只蚂蚁感冒了。
第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数。接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。(其中,哪只蚂蚁感冒是随机的)
示例


二、思路

这道题原本我是想的如果碰面就掉头这种情况去算,但是发现思路过于复杂,而且代码不是很好写(当然如果有大佬可以这样写出来的话,可否让我看一下下),所以思考了好久。观察题中所给的示例发现,如果两个蚂蚁碰头,他们除了朝向与原先不同(当然如果其中有一只感冒,那么另一只会感冒)外,他们的速度,碰撞后的位置均相同,那么不妨假设,如果两个蚂蚁碰面后并没有转头,而是穿过了彼此的身体继续向前走,那么就会变得简单一点,以题中所给的例子为例

假设如果最初处于-20的蚂蚁感冒,那么假设碰撞后彼此穿越身体的话,5只蚂蚁均感冒,但是如果最初处于12的蚂蚁感冒的话,那么处于25位置的蚂蚁最终不会感冒,剩下四只均感冒,那么大概可以得出如下结论:
如果所有蚂蚁初始朝向均相同,那么最终只有1只蚂蚁感冒,且那只蚂蚁为最初感冒的那只,而如果最初有一些蚂蚁与感冒的蚂蚁朝向不同,那么进行再进行判断,
(1)如果与最初感冒蚂蚁朝向不同的蚂蚁已经在感冒蚂蚁的身后,那么不会感冒,反之,如果在身前,那么会感冒(用代数表达就是两个蚂蚁最初位置的差的绝对值如果大于100那么不会感冒,反之会感冒),
(2)而与感冒蚂蚁相同朝向且在它身后的蚂蚁是否感冒取决于(1),如果(1)为真(即有朝向相反的蚂蚁被传染感冒),那么蚂蚁感冒,反之蚂蚁不感冒(语言不是很好,多多见谅)


三、实现的过程

通过以上的思路,我们发现主函数并不困难,我们所需要的只是输入蚂蚁的个数以及将每个蚂蚁的位置去存入一个数组中即可,然后通过设置一个计算函数去完成。这个数组中第一行放置所有蚂蚁的位置,而第二行放置的数字为感冒蚂蚁分别为第几只蚂蚁,而此顺序并不一定是感染顺序,例如下图

该结果显示第2只蚂蚁(位置处于-20)为初始感冒蚂蚁,而其后被感染的蚂蚁为第三只(位置处于12),第一只(位置处于-10),第四只(位置处于8),第五只(位置处于25),其中第三只并不是第一只被初始感冒蚂蚁所感染的蚂蚁(其实真实情况是第五只蚂蚁为第一只被感染的蚂蚁),并且最后的感冒总数为5。那么代码我们可以写成这样。

1.主函数

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{int n, a[2][50], s = 1;///s为感冒蚂蚁的个数printf("Please input a number n:");scanf("%d", &n);///输入一共有多少只蚂蚁for (int i = 0; i < n; i++)scanf("%d", &a[0][i]);///输入每一只蚂蚁所在的位置candiate(n, &a[0], &s);///传入每个蚂蚁的位置并计算感冒蚂蚁的个数以及他们分别属于第几只蚂蚁printf("\ns=%d\n", s);return 0;
}

2.初始感冒蚂蚁的设置

而主函数中的candiate函数就是我们所需要解决的重点与难点,而最开始我们需要设定一只幸运的蚂蚁去当初始感冒蚂蚁(由于数组是从0开始,而蚂蚁的个数从1开始,并且随机数的范围是在[0,n-1]中,所以在产生随机数后我们需要将其加一,才可以得到初始感冒蚂蚁为第几只蚂蚁,例如我们随机值为1,其所表达的是第一列数组中a[1]蚂蚁感冒,即第二只感冒)

int j, key1 = 0, key2 = 1, number;srand((unsigned)time(NULL));///随机挑选一个幸运的蚂蚁感冒j = rand() % s;///因为随机的是数组下标所以要求生成的随机数在[0,n-1]之内*(*(a + 1)) = j + 1;///将最初感冒的蚂蚁保存在数组的第二行的第一个元素中

3.感冒蚂蚁的判定

这里我分了两种情况,初始感冒蚂蚁是向左移动还是向右移动。

if (a[0][j] > 0)///如果感冒的蚂蚁向右爬{for (int m = 0, c = 1; m < s; m++){number = c;if (a[0][m] < 0 && a[0][j] - a[0][m] < 100)///如果满足条件(1)那么感冒蚂蚁个数增加并且将其初始位置记录到数组第二列中{*(*(a + 1) + c) = m + 1;c++;*sum += 1;key1 = 1;}if (key1 == 1 && key2 == 1)///设置两个开关是为了防止满足条件(2)的蚂蚁多次重复被记录到数组第二列中,如果条件(1)成立,那么在完成记录满足条件(2)的蚂蚁个数与位置后立即关闭key2for (int t = 0; t < s; t++)if (*(*a + t) < *(*a + j) && *(*a + t) > 0){*(*(a + 1) + c) = t + 1, * sum += 1;c++;key2 = 0;}}for (int m = 0; m < number; m++)///列举出所有感冒的蚂蚁printf("%d ", *(*(a + 1) + m));///其中第一个元素为初始感冒蚂蚁所在的位置}

key1,key2的设置是为了防止多次判断满足条件(2)的蚂蚁是否存在而导致重复计数。

 if (a[0][j] < 0)///如果蚂蚁向左爬{for (int m = 0, c = 1; m < s; m++){number = c;if (a[0][m] > 0 && a[0][j] - a[0][m] > -100)///情况于上面相同{*(*(a + 1) + c) = m + 1;c++;*sum += 1;key1 = 1;}if (key1 == 1 && key2 == 1)for (int t = 0; t < s; t++)if ((*(*a + t) > *(*a + j)) && *(*a + t) < 0){*(*(a + 1) + c) = t + 1, * sum += 1;c++;key2 = 0;}}for (int m = 0; m <= number; m++)///列举出所有感冒的蚂蚁printf("%d ", *(*(a + 1) + m));///其中第一个元素为初始感冒蚂蚁所在的位置}

综上,我们最后写出如下代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void candiate(int s, int(*a)[50], int* sum);///计算有多少只蚂蚁感冒
int main()
{int n, a[2][50], s = 1;printf("Please input a number n:");scanf("%d", &n);for (int i = 0; i < n; i++)scanf("%d", &a[0][i]);candiate(n, &a[0], &s);printf("\ns=%d\n", s);return 0;
}
void candiate(int s, int(*a)[50], int* sum)
{int j, key1 = 0, key2 = 1, number;srand((unsigned)time(NULL));///随机挑选一个幸运的蚂蚁感冒j = rand() % s;///因为随机的是数组下标所以要求生成的随机数在[0,n-1]之内*(*(a + 1)) = j + 1;///将最初感冒的蚂蚁保存在数组的第二行的第一个元素中if (a[0][j] > 0)///如果感冒的蚂蚁向右爬{for (int m = 0, c = 1; m < s; m++){number = c;if (a[0][m] < 0 && a[0][j] - a[0][m] < 100)///如果满足条件(1)那么感冒蚂蚁个数增加并且将其初始位置记录到数组第二列中{*(*(a + 1) + c) = m + 1;c++;*sum += 1;key1 = 1;}if (key1 == 1 && key2 == 1)///设置两个开关是为了防止满足条件(2)的蚂蚁多次重复被记录到数组第二列中,如果条件(1)成立,那么在完成记录满足条件(2)的蚂蚁个数与位置后立即关闭key2for (int t = 0; t < s; t++)if (*(*a + t) < *(*a + j) && *(*a + t) > 0){*(*(a + 1) + c) = t + 1, * sum += 1;c++;key2 = 0;}}for (int m = 0; m < number; m++)///列举出所有感冒的蚂蚁printf("%d ", *(*(a + 1) + m));///其中第一个元素为初始感冒蚂蚁所在的位置}if (a[0][j] < 0)///如果蚂蚁向左爬{for (int m = 0, c = 1; m < s; m++){number = c;if (a[0][m] > 0 && a[0][j] - a[0][m] > -100)///情况于上面相同{*(*(a + 1) + c) = m + 1;c++;*sum += 1;key1 = 1;}if (key1 == 1 && key2 == 1)for (int t = 0; t < s; t++)if ((*(*a + t) > *(*a + j)) && *(*a + t) < 0){*(*(a + 1) + c) = t + 1, * sum += 1;c++;key2 = 0;}}for (int m = 0; m <= number; m++)///列举出所有感冒的蚂蚁printf("%d ", *(*(a + 1) + m));///其中第一个元素为初始感冒蚂蚁所在的位置}
}

总结

其实这个代码并不是很尽如人意,例如输出的顺序可以为被感染顺序,而且这个代码也有很多优化的地方,比如向左爬和向右爬几乎相同,所以应该可以进行合一,只不过自己现在代码能力还是太弱了。希望各位大佬能多多支持,指出其中的不足指出。阿里嘎多~

练——C语言练习蚂蚁感冒相关推荐

  1. 蓝桥杯 1454 蚂蚁感冒 (找规律)

    题目描述 长100厘米的细长直杆子上有n只蚂蚁.它们的头有的朝左,有的朝右. 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒. 当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行. 这些蚂蚁中,有1只蚂 ...

  2. nyoj990蚂蚁感冒

    //其实遇到返回和遇到穿过是一样的 //既然要相遇穿过,那与蚂蚁方向相反且在它前面的就会感染 //而前面那些又会感染与之方向相反且在它前面的(与原先蚂蚁同方向,在它后面的) //注意特殊情况  #in ...

  3. NYOJ 990 蚂蚁感冒

    蚂蚁感冒 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 长100厘米的细长直杆子上有n只蚂蚁.它们的头有的朝左,有的朝右. 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/ ...

  4. 2014年第五届蓝桥杯 - 省赛 - C/C++大学A组 - G. 蚂蚁感冒

    标题:蚂蚁感冒 长100厘米的细长直杆子上有n只蚂蚁.它们的头有的朝左,有的朝右. 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒. 当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行. 这些蚂蚁中,有 ...

  5. [蓝桥杯][历届试题]蚂蚁感冒(模拟)

    题目描述 长100厘米的细长直杆子上有n只蚂蚁.它们的头有的朝左,有的朝右. 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒. 当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行. 这些蚂蚁中,有1只蚂 ...

  6. [蓝桥杯] 蚂蚁感冒

    [蓝桥杯] 蚂蚁感冒 峰值内存消耗 < 256M CPU消耗  < 1000ms [题目描述 - Problem Description] 长100厘米的细长直杆子上有n只蚂蚁.它们的头有 ...

  7. c语言编程每日一练教程,每日一练 | C语言之指针

    原标题:每日一练 | C语言之指针 练习导言 学习 C 语言的指针既简单又有趣.通过指针,可以简化一些 C 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的.所以,想要成为一名优秀的 ...

  8. 第七届蓝桥杯省赛---蚂蚁感冒

    长100厘米的细长直杆子上有n只蚂蚁.它们的头有的朝左,有的朝右. 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒. 当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行. 这些蚂蚁中,有1只蚂蚁感冒了. ...

  9. 有意思的逻辑思维题(三)(hdu2211,蓝桥杯蚂蚁感冒)

    杀人游戏 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2211 题目描述: 现在已知有N个土匪站在一排,每个土匪都有一个编号,从1到N,每次杀人时给 ...

最新文章

  1. Spark读取HDFS上的Snappy压缩文件所导致的内存溢出问题 java.lang.OutOfMemoryError: GC overhead limit exceeded
  2. Java JDBC篇2——JDBC增删查改
  3. (软件工程复习核心重点)第二章可行性研究-第三节:数据流图
  4. Makefile之嵌套执行(9)
  5. 将应用制作成镜像发布到服务器k8s上作为容器微服务运行。
  6. IOS开发之MapKit框架的使用
  7. Gallery3d 学习笔记(14)
  8. JVisualVM的使用教程
  9. 图神经网络的实现,神经网络框架图
  10. 【前端小白】pxcook读取psd设计文件
  11. SpringBoot Web开发
  12. 读书笔记:《Designing Data-Intensive Applications》
  13. Google DeepMind顾问预言:五年后AI将在《星际争霸》中战胜人类
  14. python保存图片的常用方法
  15. kali安装burpsuite专业版
  16. Java入门日记1 | 第一周总结
  17. 【2022应届生的入职感悟】
  18. AutoDL 算力云 服务器租用教程
  19. 2019爪哇部落第十届新生选拔赛 题解
  20. java 展开收起列表组件_ExpandableListView(可展开的列表组件)的说明以及其用法...

热门文章

  1. app 性能测试
  2. 论文解读:《Mouse4mC-BGRU:用于预测小鼠基因组中DNA N4-甲基胞嘧啶位点的深度学习》
  3. 分数的大小比较优秀教案_小学数学冀教版三年级下册 八 分数的初步认识《分数大小的比较》优质课公开课教案教师资格证面试试讲教案 -...
  4. Ubuntu使用splint查找C代码的BUG
  5. android巴士!这份字节跳动历年校招Android面试真题解析,面试必问
  6. 3月9号 Ares在力场和浪客行社区直播总结
  7. 【云服务器】如何搭建自己的百度云服务器?
  8. 抖音上用记事本写“爱心”小程序教程
  9. 干货 | android下使用的渗透工具介绍
  10. VUE实现时间轴播放组件