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

文章目录

  • 一、题目
  • 二、思路
  • 三、实现的过程
    • 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. Database design best practice(1):关于primary key及其它
  2. 【干货】PMcaff干货课程学习精彩分享:Apple Watch 技术特性详解
  3. c++string转char数组_C++ 算法题解:打印沙漏、素数对猜想、数组元素循环右移问题...
  4. iOS 使点击事件穿透透明的UIView
  5. enum中使用中文 unity_自定义Unity材质Inspector之枚举类型(Enum)
  6. wireshark 过滤表达式
  7. python 内存管理
  8. 刀塔霸业android安装包,刀塔霸业安卓下载-刀塔霸业安卓官网版(dota2自走棋)下载v1.0...
  9. Tor 正在开发匿名即时聊天工具
  10. java txt 分段读取_Java 读取TXT文件的多种方式
  11. IPHONE屏幕大小,分辨率解析
  12. 爬取天眼查 的python 代码
  13. 计算机中的信息表示教学计划,人教版小学五年级信息技术教学计划(小编推荐)...
  14. asp.net909-大型社区包裹代收与分发系统
  15. 小企业无线局域网服务器,无线局域网AAA服务器的软件设计与实现
  16. linux下discus/apache服务器,局域网内无法访问--解决办法
  17. 【2021 MCM】 Problem A: Fungi by 2100454
  18. Windows10下利用Visual Studio Code搭建C语言开发环境
  19. LeetCode力扣刷题——居合斩!二分查找
  20. 机器学习实战 2.5机器学习算法的数据准备

热门文章

  1. 西安三本哪个计算机学校最好,西安三本大学前十名 西北大学现代学院仅第四...
  2. 蜜汁头文件slow slow read
  3. reactXP入坑指南——写给自己
  4. html5我的心灵小屋,我的小屋
  5. 360奇安信和SonarQube漏洞及bug修改
  6. 纯前端实现一键生成二维码
  7. 疯狂python讲义epub,疯狂英语阅读版CR201510.pdf
  8. 正序分解整数C语言实现
  9. count(*)和count(字段名)和count(1)
  10. 当Python爬虫遇到JS加密