首页 > 试题广场 >

返回公司

[编程题]返回公司
  • 热度指数:898 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
度度熊迷路了他想返回他的公司,他现在在号点,他的公司在号点。度度熊所在的城市由个点和条边组成,因为度度熊走了一天了很累,他还有走两条边的体力,度度熊想知道他能否回到公司呢?

输入描述:
第一行一个数表示数据组数
每组数据第一行两个数。含义见题意。
接下来m行每行两个数a_i,b_i表示a_ib_i之间有一条边


输出描述:
每组数据一行如果能回到公司输出“POSSIBLE”,不能输出"IMPOSSIBLE"。
示例1

输入

1
4 3
1 2
2 3
3 4

输出

IMPOSSIBLE
用 Map + List 表示图
import java.util.*;
import java.util.LinkedList;

public class Main {
    public static boolean isTouch;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        while (T -- > 0) {
            isTouch = false;
            int n = sc.nextInt();
            int m = sc.nextInt();
            Map<Integer, List<Integer>> map = new HashMap<>();
            while (m -- > 0) {
                int a = sc.nextInt();
                int b = sc.nextInt();
                List<Integer> tmpList = map.getOrDefault(a, new ArrayList<>());
                tmpList.add(b);
                map.put(a, tmpList);
                tmpList = map.getOrDefault(b, new ArrayList<>());
                tmpList.add(a);
                map.put(b, tmpList);
            }
            boolean[] vis = new boolean[n];
            vis[0] = true;
            helper(map, vis, 1, n, 2);
            System.out.println(isTouch == true ? "POSSIBLE" : "IMPOSSIBLE");
        }
    }
    public static void helper(Map<Integer, List<Integer>> map, boolean[] vis, int start, int end, int tili) {
        if (isTouch) return;
        if (tili == 0) {
            if (start == end) {
                isTouch = true;
            }
            return;
        }
        if (map.containsKey(start)) {
            List<Integer> tmpList = map.get(start);
            for (int t : tmpList) {
                if (vis[t - 1]) continue;
                vis[t - 1] = true;
                helper(map, vis, t, end, tili - 1);
                vis[t - 1] = false;
            }
        }
    }
}


发表于 2021-09-07 14:52:10 回复(0)
// 标准bfs

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        // T组数据
        for (int i = 0; i < T; i++) {
            // n个点,m条边
            int n = sc.nextInt();
            int m = sc.nextInt();

            HashSet<Integer> visited = new HashSet<>();
            Map<Integer, List<Integer>> neighbors = new HashMap<>();
            for (int j = 0; j < n; j++) {
                neighbors.put(j + 1, new ArrayList<>());
            }

            for (int j = 0; j < m; j++) {
                int point1 = sc.nextInt();
                int point2 = sc.nextInt();
                List<Integer> list1 = neighbors.get(point1);
                list1.add(point2);
                neighbors.put(point1, list1);
                List<Integer> list2 = neighbors.get(point2);
                list2.add(point1);
                neighbors.put(point2, list2);
            }

            boolean flag = false;

            int length = 0;
            Queue<Integer> queue = new LinkedList<>();
            queue.add(1);
            while (!queue.isEmpty() && !flag) {
                int size = queue.size();
                length++;
                for (int j = 0; j < size; j++) {
                    int point = queue.poll();
                    if (point == n && length == 3) {
                        flag = true;
                    }
                    visited.add(point);
                    List<Integer> nexts = neighbors.get(point);
                    for (int k = 0; k < nexts.size(); k++) {
                        int next = nexts.get(k);
                        if (!visited.contains(next)) {
                            queue.add(next);
                        }
                    }
                }
            }
            if (flag){
                System.out.println("POSSIBLE");
            }else {
                System.out.println("IMPOSSIBLE");
            }
        }
    }

}  

发表于 2022-03-07 20:14:48 回复(1)
方法一:采用 Dijkstra 算法,求解 1 到 n 的最短距离是否 <= 2
方法二:1 到 n 的距离 <= 2,只需要满足下面两个条件的其中一个:
    (1) 1 和 n 之间有一条边,距离为 1
    (2) 1 和 n 包含公共的邻接节点,距离为 2
我们这里采用方法二解答。数据量比较答,采用 BufferedReader 更节省时间
import java.util.*;
import java.io.*;

public class Main {
    private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

    // 读取一个整数
    private static int read() throws IOException {
        Integer res = null;
        boolean isNative = false;
        for (;;) {
            int ch = reader.read();
            if (Character.isDigit(ch)) {
                res = (res == null ? 0 : res * 10) + (ch - '0');
            } else if (ch == '-') {
                isNative = true;
            } else if (res == null && ch != -1) {
                continue;
            } else if (res == null || !isNative) {
                return res;
            } else {
                return -res;
            }
        }
    }

    public static void main(String[] args) throws IOException {
        int T = read();
        while (T-- > 0) {
            int n = read(), m = read();
            // 1 的邻接节点
            Set<Integer> set1 = new HashSet<>();
            // n 的邻接节点
            Set<Integer> setn = new HashSet<>();
            // 读取邻接边
            for (int i = 0; i < m; ++i) {
                int a = read(), b = read();
                // 保证 a < b
                if (a > b) {
                    a ^= b;
                    b ^= a;
                    a ^= b;
                }
                // 如果 a 是 1,放入集合
                if (a == 1) {
                    set1.add(b);
                }
                // 如果 b 是 n,放入集合
                if (b == n) {
                    setn.add(a);
                }
            }
            boolean result = false;
            // 1 和 n 之间有一条边,距离为 1
            if (set1.contains(n)) {
                result = true;
            }
            // 1 和 n 包含公共的邻接节点,距离为 2
            else {
                for (Integer i : set1) {
                    if (setn.contains(i)) {
                        result = true;
                        break;
                    }
                }
            }
            // 输出结果
            System.out.println(result ? "POSSIBLE" : "IMPOSSIBLE");
        }
    }
}


发表于 2023-08-23 11:16:01 回复(0)
终于做对了一道题,家人们,可以点个赞鼓励一下不

这道题特殊在初始节点和末尾节点都是已知的,而且只走两条边
所以只需要考虑:
        1. 1 和 n 是否直接连通
        2. 1 和 n 是否通过其他的一个节点连通,即1和 n 可达节点是否有交集
其他无关节点的连通与否不用考虑

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //循环次数
        int t = scanner.nextInt();
        for (int i = 0; i < t; i++) {
            //接收第一组数据
            int n = scanner.nextInt();
            int m = scanner.nextInt();
            //状态标记
            boolean flag = false;
            
            //节点1可连通点的集合
            Set<Integer> set1 = new HashSet<>();
            //节点n可连通点的集合
            Set<Integer> setn = new HashSet<>();
            for (int j = 0; j < m; j++) {
                int node1 = scanner.nextInt();
                int node2 = scanner.nextInt();
                //判断输入边的两个端点是否含有1或者n
                //都不含的话就不用管了
                //含1的话把另外一个点放入set1
                if (node1 == 1 || node2 == 1) {
                    //判断 1 和 n 是否直接连通,是的话就改变标记flag
                    //这个不能漏,否则setn中不含1,两集合没有交集,输出IMPOSSIBLE
                    if (node1 == n || node2 == n){
                        flag = true;
                    }
                    set1.add(node1 == 1 ? node2 : node1);
                }else if (node1 == n || node2 == n) {
                    //含n的话把另外一个点放入setn
                    setn.add(node1 == n ? node2 : node1);
                }

            }

            //判断 set1 和 setn 是否有交集
            if (!flag){
                for (int num : set1){
                    if (setn.contains(num)) {
                        //有交集就改变标记
                        flag = true;
                    }
                }
            }

            System.out.println(flag ? "POSSIBLE" : "IMPOSSIBLE");
        }
    }


}

发表于 2021-10-30 21:11:08 回复(0)
刚开始做的时候,想也没想就是二维数组,后面直接超限。所以使用键值对和列表试一下,就A了
具体思路就是,对于每一个点其所能到达的点使用List来存储,并以该点为键保存。
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int t = input.nextInt();
        for (int i = 0; i < t; i++) {
            int n = input.nextInt(), m = input.nextInt();
            Map<Integer, List<Integer>> map = new HashMap<>();
            int count = 2;
            for (int j = 0; j < m; j++) {
                int x = input.nextInt(), y = input.nextInt();
                List<Integer> tempList = map.getOrDefault(x, new ArrayList<>());
                tempList.add(y);
                map.put(x, tempList);
                tempList = map.getOrDefault(y, new ArrayList<>());
                tempList.add(x);
                map.put(y, tempList);
            }
            Main main = new Main();
            if (main.findWay(map, 1, count, n)) {
                System.out.println("POSSIBLE");
            } else {
                System.out.println("IMPOSSIBLE");
            }
        }

    }

    /**
     * 寻找通路,使用递归
     * @param map 道路的地图
     * @param x 当前所在的点
     * @param count 体力值
     * @param end 终点,也可以使用全局变量
     * @return 是否可达
     */
    public boolean findWay(Map<Integer, List<Integer>> map, Integer x, int count, int end) {
        if (x == end && count >= 0) {
            // 如果到了终点,且体力值不为负数,则可通
            return true;
        } else if (x != end && count <= 0) {
            // 没到达重点,就没体力了,则不通
            return false;
        } else {
            // 否则进行递归
            if (map.containsKey(x)) {
                List<Integer> tempList = map.get(x);
                for (Integer y : tempList) {
                    if (y < x) {
                        // 不能往回走,不然绕着走会内存超限
                        continue;
                    }
                    if (findWay(map, y, count - 1, end)) {
                        return true;
                    }
                }
            }
            return false;
        }
    }
}


发表于 2022-03-22 16:46:57 回复(1)

C++ bfs求最短路

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 5;
vector<int> g[maxn];
int inq[maxn];

bool solve() {
    int n, m, u, v;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) g[i].clear();
    for (int i = 1; i <= m; ++i) {
        scanf("%d%d", &u, &v);
        g[u].push_back(v);
        g[v].push_back(u);
    }

    memset(inq, 0, sizeof(inq));
    queue<int> q;
    q.push(1);
    inq[1] = true;
    int dis = 0;
    while (!q.empty()) {
        int sz = q.size();
        while (sz--) {
            int cur = q.front(); q.pop();
            if (cur == n) return true;
            for (int v : g[cur]) {
                if (inq[v]) continue;
                inq[v] = true;
                q.push(v);
            }
        }
        if (dis++ == 2) break;
    }
    return false;
}

int main() {
    int t; cin >> t;
    while (t--) {
        if (solve()) puts("POSSIBLE");
        else puts("IMPOSSIBLE");
    }
    return 0;
}
发表于 2023-03-24 19:37:57 回复(0)
T=int(input())
for t in range(T):
    n,m=list(map(int,input().split()))
    s1,s2=set(),set()
    for i in range(m):
        a,b=list(map(int,input().split()))
        if a==1:
            s1.add(b)
        if b==n:
            s2.add(a)
    if len(s1&s2)>0 or n in s1 or 1 in s2:
        print("POSSIBLE")
    else:
        print("IMPOSSIBLE")

大佬们,为啥不对呢,样例也看不到
编辑于 2023-03-12 19:04:34 回复(0)
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;


class Point {
    int index;
    List<Point> neighbor;
    boolean alreadyPassed = false;

    public Point(int index) {
        this.index = index;
        this.neighbor = new ArrayList<>();
    }
}

public class Main {
    static boolean res;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        for (int i = 0; i < T; i++) {
            res = false;
            int n = sc.nextInt();
            int m = sc.nextInt();
            //Point[]数组用来帮助保存相邻关系
            Point[] points = new Point[n];
            for (int j = 0; j < n; j++) {
                points[j] = new Point(j + 1);
            }
            for (int j = 0; j < m; j++) {
                int a = sc.nextInt() - 1;
                int b = sc.nextInt() - 1;
                points[a].neighbor.add(points[b]);
                points[b].neighbor.add(points[a]);
            }
            points[0].alreadyPassed = true;
            recur(points[0], 2, n);
            System.out.println(res ? "POSSIBLE" : "IMPOSSIBLE");
        }
    }

    private static void recur(Point point, int count, int n) {
        if (res || count < 0) return;
        if (point.index == n) {
            res = true;
            return;
        }
        for (Point neighbor : point.neighbor) {
            if (neighbor.alreadyPassed) continue;
            neighbor.alreadyPassed = true;
            recur(neighbor, count - 1, n);
            neighbor.alreadyPassed = false;
        }
    }
}

发表于 2022-09-13 16:40:09 回复(0)
import java.util.*;

public class Main{
        public static void main(String[] args) throws Throwable {
            Scanner in = new Scanner(System.in);
            int T = in.nextInt();
            for(int t = 0; t < T; t++)
            {
                int n = in.nextInt();
                int m = in.nextInt();
                int[] deep = new int[n + 1];
                for (int i = 0; i < n + 1; i++) {
                    deep[i] = 100;
                }
                deep[1] = 1;
                int[][] num = new int[m][2];
                for (int i = 0; i < m; i++) {
                    int x1 = in.nextInt();
                    int x2 = in.nextInt();
                    num[i][0] = x1;
                    num[i][1] = x2;
                }
                Arrays.sort(num, (arr1, arr2) -> arr1[0] == arr2[0] ? arr1[1] - arr2[1] : arr1[0] - arr2[0]);
                for (int i = 0; i < m; i++) {
                    if(num[i][0] > num[i][1])
                    {
                        int temp = num[i][0];
                        num[i][0] = num[i][1];
                        num[i][1] = temp;
                    }
                    deep[num[i][1]] = Math.min(deep[num[i][0]] + 1, deep[num[i][1]]);
                }
                System.out.println(deep[n] > 3 ? "IMPOSSIBLE" : "POSSIBLE");
            }
        }
}

发表于 2022-09-13 12:35:19 回复(0)
import java.lang.reflect.Array;
import java.util.*;

public class Main {

    static class State{
        public int id;
        public int dist;
        public State(int id,int dist) {
            this.id=id;
            this.dist=dist;
        }
    }
    static List<Integer>[] grapLists;
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        for(int l=0;l<t;l++) {
            int n=sc.nextInt();
            int m=sc.nextInt();
            grapLists=new List[n+1];
            for(int i=1;i<=n;i++) {
                grapLists[i]=new ArrayList<>();
            }
            for(int i=0;i<m;i++) {
                int a=sc.nextInt();
                int b=sc.nextInt();
                grapLists[a].add(b);
                grapLists[b].add(a);
            }
            int[] distTo=new int[n+1];
            Arrays.fill(distTo, Integer.MAX_VALUE);
            distTo[1]=0;
            PriorityQueue<State> pq=new PriorityQueue<>(new Comparator<State>() {
                @Override
                public int compare(State o1, State o2) {
                    return o1.dist-o2.dist;
                }
            });
            pq.add(new State(1,0));
            while (!pq.isEmpty()){
                State poll = pq.poll();
                if(poll.dist>2){
                    System.out.println("IMPOSSIBLE");
                    break;
                }
                if(poll.id==n){
                    System.out.println("POSSIBLE");
                    break;
                }
                if(distTo[poll.id]<poll.dist){
                    continue;
                }
                List<Integer> list = grapLists[poll.id];
                for (Integer integer : list) {
                    int newDist=poll.dist+1;
                    if(newDist<distTo[integer]){
                        distTo[integer]=newDist;
                        pq.add(new State(integer,newDist));
                    }
                }
            }
        }
        sc.close();
    }
}


图的遍历

编辑于 2022-03-02 20:40:47 回复(0)
import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int T = sc.nextInt();
            for(int i=0; i<T; i++){
                int n = sc.nextInt();
                int m = sc.nextInt();
                List<Integer>[] graph = new ArrayList[n+1];
                for(int j=0; j<graph.length; j++){
                    graph[j] = new ArrayList<>(); 
                }
                
                for(int j=0; j<m; j++){
                    int a = sc.nextInt();
                    int b = sc.nextInt();
                    graph[a].add(b);
                    graph[b].add(a);
                }
                String outline = "IMPOSSIBLE";
                if(!(graph[1].isEmpty() && graph[n].isEmpty())){
                  for(Integer tmp: graph[1]){
                        if(graph[n].contains(tmp)){
                            outline = "POSSIBLE";
                            break;
                        }                        
                    }
                }

                System.out.println(outline);
            }
        }

    }
}
发表于 2021-05-29 16:52:17 回复(0)