zoukankan      html  css  js  c++  java
  • 2016奇虎360研发工程师内推笔试编程题:找镇长

    360员工桂最近申请了一个长假,一个人背着包出去自助游了。
      路上,他经过了一个小镇,发现小镇的人们都围在一棵树下争吵。桂上前询问情况,得知小镇的人们正缺一个镇长,他们希望能选一个知名又公正的镇长,即,大家希望能选出一个人,所有人都认识他,但同时他不认识镇上除自己以外的其他人(在此,我们默认每个人自己认识自己)。可是小镇里的人太多了,一下子大家谁也说服不了谁。
      “这简单啊。”桂表示。于是他一下子统计出来了镇上人们相互之间的认识关系,并且一下子找到了合适的镇长人选。
      现在你手上也拿到了这样一份认识关系的清单。其中上面给出的认识关系是单向的,即,A认识B与B认识A是相互独立的,只给出A认识B就不能认为B认识A,例如,我认识你,你不一定认识我。而且,这里的认识关系也不具有传递性,即,A认识B,B认识C,但这不代表A认识C。同时,为了方便处理,这份清单中,镇上的N个人依次编号为1到N。你能否像桂一样快速找到合适的镇长人选呢? 
    输入描述:
    首先一个正整数T(T≤20),表示数据组数。
    之后每组数据的第一行有2个整数n  和m  (1≤n≤105 ,0≤m≤3×105 ),依次表示镇上的人数和相互之间的认识关系数。
    之后m行,第 i 行每行两个数Ai和Bi   (1≤Ai ,Bi ≤n  ),表示Ai认识Bi。(保证没有重复的认识关系,但可能存在自己认识自己的认识关系)
    保证所有数据中80%的数据满足n≤1000,m≤10000
    输出描述:
    一共2T 行,每组数据对应2行。
    第一行,一个整数,表示你所找出来的合适的镇长人选人数num i   。
    第二行,num i 个整数,每两个数中间用空格隔开,表示你所选的合适的镇长的编号。
    特别的,如果并没有找到合适的镇长,第一行输出一个数0,第二行留空即可(参见样例)。
    输入例子:
    3
    2 0
    3 2
    1 2
    3 2
    4 5
    1 1
    2 1
    3 1
    4 1
    3 3
    输出例子:
    0
    
    1
    2
    1
    1

    解题

    题意:找到其他人都认识他,而他都不认识其他人的那个他
    定义人数的矩阵,表示关系
    A[i][j] 表示 i 人 与 j人的关系,为 1 的时候表示认识 ,0 不认识,i==j 表示自己认识自己
    答案满足:
    该 i 行只有 A[i][i] 为1,其他都为 0
    该 i 列元素都为 1

     1 package a_360;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Scanner;
     5 
     6 public class Main{
     7 
     8     /**
     9      * 题目:
    10      * 找出别人都认识他,而他其他人都不认识的人
    11      * 输入:
    12      * T T个这样的测试样例
    13      * n m n个人 m个关系数
    14      * 下面m行就是关系数
    15      * 输出:
    16      * 第一行:这样的人有几个
    17      * 满足条件人的编号
    18      * 
    19      * 若不存在,输出 0 空格
    20      */
    21     public static void main(String[] args) {
    22         // TODO Auto-generated method stub
    23         Scanner scn = new Scanner(System.in);
    24         int T = scn.nextInt(); // 测试数据组数
    25         for (int i = 0; i < T; i++) {
    26             int n = scn.nextInt(); // 人数
    27             int m = scn.nextInt(); // 关系数
    28             if(m==0 || n==1){
    29                 System.out.println(0);
    30                 System.out.println();
    31                 continue;
    32             }
    33             int[][] A = new int[n][n];
    34             
    35             for(int k =0;k<m;k++){
    36                 int m1 = scn.nextInt();
    37                 int m2 = scn.nextInt();
    38                 A[m1-1][m2-1] = 1;
    39             }
    40             // 对角值为 1 
    41             for(int k =0;k<n;k++){
    42                 A[k][k] = 1;
    43             }
    44             relation_0(A);
    45         }
    46     }
    47 
    48     public static void relation_0(int[][] A){
    49         // 关系已经存在二维数组中,找出二维数组中行只有对角位置是1 ,对角位置所在的列都是 1
    50         int count = 0;
    51         ArrayList<Integer> res = new ArrayList<Integer>();
    52         for(int i = 0;i<A.length;i++){
    53             boolean row1 = true;
    54             boolean col1 = true;
    55             // 判断第 i列是否都是1 都是1 说明别人都认识他
    56             for(int row = 0;row<A.length;row++){
    57                 if(A[row][i] == 0){
    58                     col1 = false;
    59                     break;
    60                 }
    61             }
    62             if(col1){
    63                 // 判断第 i 行是否只有对角是 1 意思 别人都不认识他,对角是自己认识自己
    64                 for(int col = 0;col<A.length;col++){
    65                     // == 1 说明有人认识他 
    66                     if(col!=i && A[i][col]==1){
    67                         row1 = false;
    68                         break;
    69                     }
    70                 }
    71             }
    72             if(row1 && col1){
    73                 count++;
    74                 res.add(i+1);
    75             }
    76         }
    77         System.out.println(count);
    78         for(int i = 0;i<res.size();i++){
    79             System.out.println(res.get(i));
    80         }
    81     }
    82 
    83 }

    牛客测试内存溢出,给的样例本地测试通过

    上面在判断列全是 1 的时候可以对改行的元素求和,和等于人数n的时候符合条件

    在判断行只有1的并且是自己认识自己的时候,可以变相的认为和是 0 

    但是上面还是不能改变定义矩阵的情况

    上面可以看到,我们用到的只是矩阵的行的和,和矩阵列的和

    定义两个向量来存放行的和和列的和。

    定义两个数组:A B

    A[i] 表示 i 认识的人数

    B[i] 表示 认识 i 的人数 

    上面去除自己认识自己的情况

    当A[i] == 0 B[i] = n-1 的时候 说明这个人不认识别人,却被 n -1个人认识就是答案

    题目中说可以有多个,其实最多只有一个,因为这个人要被其余 n -1 个人认识,就不存在两个人的情况了

    在牛客不知道为什么下面程序提示“运行错误:请检查是否存在数组越界非法访问,野指针乱访问,空指针乱访问等情况”

     1 import java.util.Scanner;
     2 
     3 public class Main {
     4 
     5     /**
     6      * 题目:
     7      * 找出别人都认识他,而他其他人都不认识的人
     8      * 输入:
     9      * T T个这样的测试样例
    10      * n m n个人 m个关系数
    11      * 下面m行就是关系数
    12      * 输出:
    13      * 第一行:这样的人有几个
    14      * 满足条件人的编号
    15      * 
    16      * 若不存在,输出 0 空格
    17      */
    18     public static void main(String[] args) {
    19         // TODO Auto-generated method stub
    20         Scanner scn = new Scanner(System.in);
    21         int T = scn.nextInt(); // 测试数据组数
    22         while((T--)>0) {
    23             int n = scn.nextInt(); // 人数
    24             int m = scn.nextInt(); // 关系数
    25             if(n == 1){
    26                 System.out.print(1+"
    "+1);
    27                 continue;
    28             }
    29             if(m<n-1){
    30                 System.out.print(0+"
    "+0);
    31                 continue;
    32             }
    33 
    34             // 认识人的数量
    35             int[] A = new int[n+1];
    36             // 被认识的数量
    37             int[] B = new int[n+1];
    38             // m1 认识 m2 
    39             for(int k =0;k<m;k++){
    40                 int m1 = scn.nextInt();
    41                 int m2 = scn.nextInt();
    42                 
    43                 if(m1!=m2){
    44                     // m1 认识的人数 去除自己的情况
    45                     A[m1]++;
    46                     //m2 被多少人认识,去除自己的情况
    47                     B[m2]++;
    48                 }
    49             }
    50             // 自己认识自己的情况可以不用考虑,A[i] = 0 表示 i 不认识除自己以外的其他人, B[i] = n-1 表示i 其他人都认识
    51             int id = -1;
    52             for(int kk = 1;kk<=n;kk++){
    53                 if(A[kk]==0 && B[kk]==n-1){
    54                     id = kk;
    55                     break;
    56                 }
    57             }
    58             if(id == -1){
    59                 System.out.print("0
    
    ");
    60             }else{
    61                 System.out.print(1+"
    "+id+"
    ");
    62             }
    63             
    64         }
    65     }
    66 
    67 
    68 }


  • 相关阅读:
    ITMS-90809
    iOS ipa 优化减小安装大小
    Xcode 常用路径
    如何查看 Assets.car 内资源
    UILabel 实现圆角
    iOS 改变 UITextField 的 Placeholder 的字体与颜色
    ATS (App Transport Security)
    iOS semaphore 使用
    macOS 自定义 NSButton
    iOS开发——设计模式那点事
  • 原文地址:https://www.cnblogs.com/bbbblog/p/5276848.html
Copyright © 2011-2022 走看看