第九届蓝桥杯javaC组第九题---小朋友崇拜圈,求大神教我,

叫我坤坤好了 2018-04-16 03:28:10
题:小朋友崇拜圈

班里N个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。
在一个游戏中,需要小朋友坐一个圈,
每个小朋友都有自己最崇拜的小朋友在他的右手边。
求满足条件的圈最大多少人?

小朋友编号为1,2,3,...N
输入第一行,一个整数N(3<N<100000)
接下来一行N个整数,由空格分开。

要求输出一个整数,表示满足条件的最大圈的人数。

例如:
输入:
9
3 4 2 5 3 8 4 6 9

则程序应该输出:
4

解释:
如图p1.png所示,崇拜关系用箭头表示,红色表示不在圈中。
显然,最大圈是[2 4 5 3] 构成的圈


再例如:
输入:
30
22 28 16 6 27 21 30 1 29 10 9 14 24 11 7 2 8 5 26 4 12 3 25 18 20 19 23 17 13 15

程序应该输出:
16
...全文
1354 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
qybao 2020-03-19
  • 打赏
  • 举报
回复
这个就是找最大环,遍历崇拜关系取下一个崇拜者的崇拜关系,一层层寻找,能形成环,取形成环的最大即可
思路挺简单的
加入LS说的测试数据
public class Sample {
public static void main(String[] args) {
int [][]num = { //测试数据
{3,4,2,5,3,8,4,6,9},
{22,28,16,6,27,21,30,1,29,10,9,14,24,11,7,2,8,5,26,4,12,3,25,18,20,19,23,17,13,15},
{2,3,4,4}
};
int max=-1, n;
List<Integer> tmp = new ArrayList<>(); //寻找用
List<Integer> res = new ArrayList<>(); //保存结果用
for (int j=0; j<num.length; j++) { //遍历取测试数据
max = -1;
res.clear();
for (int i=0; i<num[j].length; i++) { //此处以下是算法的开始,遍历崇拜关系
if (res.contains(i+1)) continue; //如果当前崇拜者被遍历过则跳过(只是为了改善性能,不要这行代码也没关系)
tmp.clear();
n = i+1; //当前崇拜者编号
tmp.add(n); //当前崇拜者加入环

while (true) { //一层层查找崇拜关系
n = num[j][n-1]; //取下一个崇拜者
if (!tmp.contains(n)) { //如果不在环中则加入环
tmp.add(n);
if (tmp.size() > num[j].length) break; //为了防止崇拜关系不正确而死循环(不存在环),正常可以不要这行代码
} else { //如果在环中(能形成环)
if (n!=i+1) {//如果最后一个崇拜者不是最开始的第一个崇拜者
tmp = tmp.subList(tmp.indexOf(n), tmp.size()); //则去掉不符合环的崇拜者
}
if (tmp.size()>max) { //如果环的人数大于max,则重新修改max,并保存环
max=tmp.size();
res.clear();
res.addAll(tmp);
}
break; //形成环则退出一层层查找崇拜关系
}
}
}
System.out.println(max); //打印最大环
System.out.println(res);
}
}
}
鸣月my 2020-03-19
  • 打赏
  • 举报
回复
引用 2 楼 Braska 的回复:

public void run() {
int[] nums = {22, 28, 16, 6, 27, 21, 30, 1, 29, 10, 9, 14, 24, 11, 7, 2, 8, 5, 26, 4, 12, 3, 25, 18, 20, 19, 23, 17, 13, 15};

Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i< nums.length; i++) {
map.put(i, nums[i]);
}

Integer maxCircle = 0;
for (Integer v : map.values()) {
List<Integer> group = Lists.newArrayList();
int nodeCount = 0;
int i = v;

while (!group.contains(i)) {
group.add(i);
i = nums[i-1];
nodeCount ++;
if (nodeCount > maxCircle) {
maxCircle = nodeCount;
}
}
}

System.out.println(maxCircle);
}


楼主的代码在加入每个元素的时候,没有考虑最后能不能形成一个圈,就直接加进去了,所以肯定是错的,原题给的数据只是恰好能通过而已。可以测试一下以下测试数据:
4
2 3 4 4
即1崇拜2,2崇拜3,3崇拜4,4崇拜4自己。显然,答案应该是1,只有4自己能形成一个圈。但是楼主的代码输出的是3,就是因为在加入每个数的时候,不考虑最后能不能形成一个圈,就直接加入了。
fiona2014 2019-01-31
  • 打赏
  • 举报
回复 1
题目没有说清楚的是,输入表达的意思,第一个数,是有多少个小朋友,比较好理解,第二行有n个数,排列的规律为崇拜编号 比如: 9 3 4 2 5 3 8 4 6 9 为一共9个小朋友,第一个小朋友仰慕3号,第二个小朋友仰慕4号,第三个小朋友仰慕2号,第四个小朋友仰慕5号,第五个小朋友仰慕3号,第六个小朋友仰慕8号,第七个小朋友仰慕4号,第八个小朋友仰慕6号,第九个小朋友仰慕9号自己。
adlLine 2018-04-22
  • 打赏
  • 举报
回复
#include <stdio.h> #include <malloc.h> int n, *a, *flag, head, max, count; void init() ; void bfs(int temp) ; int main() { int i; init(); for(i=0; i<n; i++) { flag[i] = 1; //标记 head = i+1; count = 0; bfs(a[i]); flag[i] = 0; //取消标记 } printf("%d", max); return 0; } void init() { int i; scanf("%d", &n); a = (int *)malloc(sizeof(int)*n); flag = (int *)malloc(sizeof(int)*n); for(i=0; i<n; i++) { scanf("%d", &a[i]); flag[i] = 0; } head = 0; //标记开始的头为0即不存在,以便最后一个找不到崇拜对象了 max = 0; //设置最大可以围成圈的人数为0 } void bfs(int temp) { int i; count++; if(temp == head) { max = max>count?max:count; } else if(flag[temp-1] == 1) { //防止进入无限递归中 return; } else { flag[temp-1] = 1; bfs(a[temp-1]); flag[temp-1] = 0; } }
叫我坤坤好了 2018-04-17
  • 打赏
  • 举报
回复
引用 2 楼 Ragin的回复:

public void run() {
        int[] nums = {22, 28, 16, 6, 27, 21, 30, 1, 29, 10, 9, 14, 24, 11, 7, 2, 8, 5, 26, 4, 12, 3, 25, 18, 20, 19, 23, 17, 13, 15};

        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i< nums.length; i++) {
            map.put(i, nums[i]);
        }

        Integer maxCircle = 0;
        for (Integer v : map.values()) {
            List<Integer> group = Lists.newArrayList();
            int nodeCount = 0;
            int i = v;

            while (!group.contains(i)) {
                group.add(i);
                i = nums[i-1];
                nodeCount ++;
                if (nodeCount > maxCircle) {
                    maxCircle = nodeCount;
                }
            }
        }
        
        System.out.println(maxCircle);
    }
谢谢大佬~~~~~~~~~
叫我坤坤好了 2018-04-17
  • 打赏
  • 举报
回复
引用 8 楼 Ragin的回复:
[quote=引用 7 楼 qq_36943438 的回复:]
那为什么非要是i-1呢 他右边的不是都可以崇拜么

看图片,单箭头的。
1号小朋友崇拜22号,那你就要去找下标21的。如果他写了1号小朋友崇拜22号和20号 那应该就可以按你的思路写。[/quote] 懂了,谢谢~~~~~~~
Braska 2018-04-17
  • 打赏
  • 举报
回复
引用 7 楼 qq_36943438 的回复:
那为什么非要是i-1呢 他右边的不是都可以崇拜么

看图片,单箭头的。
1号小朋友崇拜22号,那你就要去找下标21的。如果他写了1号小朋友崇拜22号和20号 那应该就可以按你的思路写。
叫我坤坤好了 2018-04-17
  • 打赏
  • 举报
回复
引用 6 楼 Ragin的回复:
[quote=引用 4 楼 qq_36943438 的回复:]
i = nums[i-1]; 为什么要这样啊

找到这个人崇拜的小朋友啊。

这段代码还可以精简。map那段没用,map.values()换成nums。[/quote] 那为什么非要是i-1呢 他右边的不是都可以崇拜么
Braska 2018-04-17
  • 打赏
  • 举报
回复
引用 4 楼 qq_36943438 的回复:
i = nums[i-1]; 为什么要这样啊

找到这个人崇拜的小朋友啊。

这段代码还可以精简。map那段没用,map.values()换成nums。
叫我坤坤好了 2018-04-17
  • 打赏
  • 举报
回复
引用 2 楼 Ragin的回复:

public void run() {
        int[] nums = {22, 28, 16, 6, 27, 21, 30, 1, 29, 10, 9, 14, 24, 11, 7, 2, 8, 5, 26, 4, 12, 3, 25, 18, 20, 19, 23, 17, 13, 15};

        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i< nums.length; i++) {
            map.put(i, nums[i]);
        }

        Integer maxCircle = 0;
        for (Integer v : map.values()) {
            List<Integer> group = Lists.newArrayList();
            int nodeCount = 0;
            int i = v;

            while (!group.contains(i)) {
                group.add(i);
                i = nums[i-1];
                nodeCount ++;
                if (nodeCount > maxCircle) {
                    maxCircle = nodeCount;
                }
            }
        }
        
        System.out.println(maxCircle);
    }
    i = nums[i-1]; 为什么要这样做?
叫我坤坤好了 2018-04-17
  • 打赏
  • 举报
回复
i = nums[i-1]; 为什么要这样啊
Braska 2018-04-16
  • 打赏
  • 举报
回复

public void run() {
        int[] nums = {22, 28, 16, 6, 27, 21, 30, 1, 29, 10, 9, 14, 24, 11, 7, 2, 8, 5, 26, 4, 12, 3, 25, 18, 20, 19, 23, 17, 13, 15};

        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i< nums.length; i++) {
            map.put(i, nums[i]);
        }

        Integer maxCircle = 0;
        for (Integer v : map.values()) {
            List<Integer> group = Lists.newArrayList();
            int nodeCount = 0;
            int i = v;

            while (!group.contains(i)) {
                group.add(i);
                i = nums[i-1];
                nodeCount ++;
                if (nodeCount > maxCircle) {
                    maxCircle = nodeCount;
                }
            }
        }
        
        System.out.println(maxCircle);
    }
叫我坤坤好了 2018-04-16
  • 打赏
  • 举报
回复
附图

50,523

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧