1. 这道题目好像属于第五届蓝桥杯的,问题描述:
长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。
每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。
当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。
这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。
请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。
输入格式
第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数。
接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。其中,第一个数据代表的蚂蚁感冒了。
输出格式
要求输出1个整数,表示最后感冒蚂蚁的数目。
样例输入
3
5 -2 8
样例输出
1
样例输入
5
-10 8 -20 12 25
样例输出
3
2. 思路分析:
① 其实题目还是比较好理解的,不要被其中的字眼“蚂蚁碰到之后会按相反的方向进行移动”所吓倒,其实自己在图上画一下图还是比较清楚的,可以分为以下几种情况,但是首先需要解决的问题是将输入的蚂蚁的位置进行调整,将其归位到相应的位置,以便模拟蚂蚁在其中杆上的位置,因为使用的是Java语言,所以没有像C++语言那样比较方便,可以声明对应的结构体数组然后使用库函数中的排序函数直接排序,这里需要声明一个内部类,这样才可以将具有符号的数字进行排序之后符号还是在原来的位置上,在输入数据的时候需要判断是否大于零,假如大于零那么说明蚂蚁的方向是向右边的,这个时候将内部类中的表示方向的属性设置为1,向左走设置为0,所以在内部类中声明两个属性即可,一个是表示数据大小的属性,一个是表示蚂蚁行走的方向
② 接下来需要对感冒的蚂蚁走的方向进行分析,假如感冒的蚂蚁向右边走,对于在其右边的蚂蚁,感染的数量总是等于一开始感冒蚂蚁右边向左边走的蚂蚁,也就是其数量是恒定的,假如两只蚂蚁碰到之后往相反的方向走,但是他们向左边走的数量是一定的,只是在碰到的时候两只蚂蚁互换了位置,对结果没有什么影响,分析了感冒蚂蚁向右走并且在其右边感冒的蚂蚁的情况,接下里就是感冒蚂蚁左边的情况了,因为感冒蚂蚁向右走,可能会碰到一只蚂蚁那么它会往相反的方向走,也就是像左边走,所以这个时候感冒蚂蚁左边的数量等于一开始数组中向右走的蚂蚁的数量,其中碰到之后只是互换了位置,对于究竟是哪个蚂蚁没有要求。
对于上面的总结来说就是,当感冒蚂蚁向右走,那么右边的感冒的数量等于感冒蚂蚁右边向左边走的数量,左边的感冒的数量等于了感冒蚂蚁向右走的数量,两个数量之和那么就是感冒蚂蚁一开始向右走之和总的数量,这个其实在图上画出来分析一下就可以知道
③ 对于第二种的感冒蚂蚁向左走的情况,在感冒蚂蚁左边感冒的数量是一开始感冒蚂蚁左边向右走的数量,因为感冒蚂蚁向左边走那么碰到第一只蚂蚁之后两只蚂蚁互换位置,所以碰到之后会向右走,这个时候感冒蚂蚁右边感冒的数量等于了感冒蚂蚁向左边走的数量,两个数量之和其实就是感冒蚂蚁一开始向右走的总的数量,在循环中可以使用两个变量进行记录分别对应感冒蚂蚁走的两种情况
总的来说对于比较复杂的需要画一下图,分析一下
3. 代码如下:
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
/*主要是为了其中能够正确排序所以声明了一个节点*/
public static class Node{
private int data;
private int dir;
public Node(int data, int dir) {
this.data = data;
this.dir = dir;
}
public Node() {
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public int getDir() {
return dir;
}
public void setDir(int dir) {
this.dir = dir;
}
@Override
public String toString() {
return "Node{" +
"data=" + data +
", dir=" + dir +
'}';
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
/*蚂蚁的总数*/
int n = sc.nextInt();
Node arr[] = new Node[n];
/*先要对象进行初始化*/
for (int i = 0; i < n; ++i){
/*新建一个对象*/
arr[i] = new Node();
}
for (int i = 0; i < n; ++i){
int t = sc.nextInt();
if (t < 0){
arr[i].data = -t;
arr[i].dir = -1;
}else {
arr[i].data = t;
arr[i].dir = 1;
}
}
//对对象数组进行排序
Comparator<Node> comp = new Comparator<Main.Node>() {
@Override
public int compare(Node o1, Node o2) {
if (o1.data > o2.data) {
return 1;
} else if (o1.data < o2.data) {
return -1;
}
return 0;
}
};
int res = numberOfIlledAnts(n, arr, comp);
System.out.println(res);
}
private static int numberOfIlledAnts(int n, Node[] arr, Comparator<Node> comp) {
int pos = arr[0].data, dir = arr[0].dir, index = -1, count1 = 0, count2 = 0;
/*for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}*/
Arrays.sort(arr, comp);
for(int i = 0; i < n; ++i){
if (pos == arr[i].data){
index = i;
break;
}
//*感冒的蚂蚁向左走的*//*
if (dir < 0 && arr[i].dir > 0){
count1++;
}
else if (dir > 0 && arr[i].dir > 0){
//*感冒的蚂蚁向右走*//*
count2++;
}
}
for (int i = index + 1; i < n; ++i){
if (dir < 0 && arr[i].dir < 0){
count1++;
}
else if (dir > 0 && arr[i].dir < 0){
++count2;
}
}
int res = 0;
if (dir > 0){
return count2 + 1;
}
return count1 + 1;
}
}