蓝桥杯 历届试题 发现环 C++

题目阅览
小明的实验室有N台电脑,编号1~N。原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络。在树形网络上,任意两台电脑之间有唯一的路径相连。
  不过在最近一次维护网络时,管理员误操作使得某两台电脑之间增加了一条数据链接,于是网络中出现了环路。环路上的电脑由于两两之间不再是只有一条路径,使得这些电脑上的数据传输出现了BUG。
  为了恢复正常传输。小明需要找到所有在环路上的电脑,你能帮助他吗?
  
输入格式
  第一行包含一个整数N。
  以下N行每行两个整数a和b,表示a和b之间有一条数据链接相连。
  对于30%的数据,1 <= N <= 1000
  对于100%的数据, 1 <= N <= 100000, 1 <= a, b <= N
  输入保证合法。
  
输出格式
按从小到大的顺序输出在环路上的电脑的编号,中间由一个空格分隔。

样例输入
5
1 2
3 1
2 4
2 5
5 3

样例输出
1 2 3 5

思路简介
首先根据题意了解到这是与数据结构中的树相关的问题,根据第一个输入画出一个树便可以很轻松的看到输出答案的闭合环路,但需要让计算机进行这一过程。
其次,我们可以观察到最后在环上的顶点,与之连接的至少有两个,所以我们可以采用记录每个顶点的连接数,然后去除掉连接个数为1的顶点树,再去掉与之连接的那条线,依次循环,最后输出时判断节点连接数为1的节点,便只剩下在环中的顶点,即答案。
在此使用可变数组与固定数组完成,一个记录节点,另外一个记录节点连接的个数,按照上面所述思想完成筛选过程,最后要求按照从小到大顺利输出,代码中直接判断节点连接个数就输出是因为固定数组中存储时已经按照顺序来存,不需要再进行排序操作,便可得到正确结果。

实现代码

#include <iostream>
#include <vector>

using namespace std;

int main(){
    int n;
    cin>>n;
    vector<int> Lists[n+1];//记录节点 
    int listCount[n+1]={0};//记录节点连接的个数 
    for(int i=0;i<n;i++){
        int a,b;
        cin>>a>>b;
        Lists[a].push_back(b);//在a节点内加入b 
        Lists[b].push_back(a);//在b节点内加入a 
        listCount[a]++;//记录a节点连接个数 
		listCount[b]++;//记录b节点连接个数 
    }
    
    for(int i=1;i<=n;i++){
        if(listCount[i]==1){//碰到叶子节点 
            int tmp1=i;
            while(listCount[tmp1]==1){//依次删除与之连接的顶点 
                int tmp2=Lists[tmp1][0];
                listCount[tmp2]--;
                tmp1=tmp2;
            }
        }
    }
    
    for(int i=1;i<=n;i++){//输出闭合回路 
        if(listCount[i]>1)
            cout<<i<<" ";
    }
    return 0;
 }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【问题描述】 一个国王因为听信谗言将一个无辜的数学家关进了监狱。虽然事后发现确属冤枉,但碍于面子,国王不肯认错。为了挽回,于是国王决定用Bytish锁链将其锁在墙上。这种锁链由n(10≤n≤1000)个固定在墙上的铁和铁棒组成。由于不是都套在棒上,要想把整副锁链取下是十分困难的。数学家必须自己通过不断取下和套上铁最终将所有铁都取下才能获得自由。取下或套上铁的规则是:  铁从1、2、……、n依次编号。  一次只能把一个取下或套上。  编号为1的无论何时都能取下或套上。  如果编号为1、……、k-1(1≤k≤n)的已经从棒上取下,并且k套在棒上,则可以取下或套上编号为k+1的。 写一个程序,读入锁链描述并计算从棒上取下所有所需的最少步数。 【基本要求】 显然,可以运用递归的方法解决此问题。但是你能否找到一个非递归算法呢? 【输入输出】 输入:的总数n。 输出:为尽量体现程序输出结果的层次,要求按照从n、n-1、n-2、……、1的顺序,将移除掉n号的全部过程作为一个段落输出,然后将移除n-1号的全部过程也作为一个段落输出,其余依此类推。 【实现提示】 显然,通过枚举前i个的解锁过程可以从中找出解题的思路。 当n=1时,直接移除即得解。 当n=2时,显然不能先移出1,再移除2。因为根据约束条件,必须1在棒上才能移除2。因此移除的步骤应该是先2,再1。 当n=3时,移除3的条件是2在,1卸,于是可以先移除1,然后移除3,然后套上1,然后移除2和1。 当n≥4的情形请自行推导。
青蛙跳杯子是蓝桥杯历届试题中的一道典型题目。题目要求模拟一个青蛙跳杯子的游戏,给定n个杯子和m次操作,每次操作可以选择一个杯子,并将其放置在当前位置前面或者后面的位置。最后,要求输出经过m次操作后,杯子从左到右的顺序。 下面是一个可能的Java代码实现: ```java import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); // 杯子的数量 int m = scanner.nextInt(); // 操作的次数 int[] cups = new int[n]; // 初始化杯子的初始顺序 for (int i = 0; i < n; i++) { cups[i] = i+1; } // 执行m次操作 for (int i = 0; i < m; i++) { int index = scanner.nextInt(); // 选择的杯子的位置 int direction = scanner.nextInt(); // 移动的方向,1表示前面,2表示后面 // 将选择的杯子移动到指定位置 if (direction == 1) { for (int j = index-1; j > 0; j--) { int temp = cups[j]; cups[j] = cups[j-1]; cups[j-1] = temp; } } else if (direction == 2) { for (int j = index-1; j < n-1; j++) { int temp = cups[j]; cups[j] = cups[j+1]; cups[j+1] = temp; } } } // 输出最终的杯子顺序 for (int i = 0; i < n; i++) { System.out.print(cups[i] + " "); } } } ``` 该代码首先读取输入的杯子数量n和操作次数m,然后创建一个数组用来保存杯子的顺序。从1到n依次填充数组的初始顺序。接下来,执行m次操作,根据输入的位置和方向调整杯子的顺序,最后输出调整后的杯子顺序。 需要注意的是,该代码没有进行输入合法性的验证,实际应用中可能需要对输入进行适当的验证和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值