2019杭电计算机学院复试笔试真题

1.大家去电影院看电影,总共有n人来看电影,其中年龄不低于18岁的成年人的座位号为奇数,不满18岁的未成年人的座位号为偶数。现在请统计成年人与未成年的数目,以及他们在总人数里的比例。n<=1000。

样例输入:5 2 3 6 7 11

样例输出:3 0.60 2 0.40


2.给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。
在这里插入图片描述
a.暴力法

void to19_2(){
    // 暴力
    int n;
    int res =0;
    cin>>n;
    int x[n];
    for(int i=0; i<n; i++){
        cin>>x[i];
    }
    for(int i=0; i<n; i++){
        for(int j=i+1; j<n; j++){
            int temp = (j-i)*min(x[i], x[j]);
            res = max(temp, res);
        }
    }
    cout<<res<<endl;
}

b.双指针法

void to19_2_t(){
    // 双指针
    int n;
    int res =0;
    cin>>n;
    int x[n];
    for(int i=0; i<n; i++){
        cin>>x[i];
    }
    int i=0, j=n-1;
    while(i<j){
        int temp = (j-i)*min(x[i], x[j]);
        res = max(res, temp);
        if(x[i] < x[j]){
            i++;
        }else {
            j--;
        }
    }   
    cout<<res<<endl;
}

4.有个班级,里面有N个学生,他们之中有些是朋友有些不是,比如如果A是B的朋友,B是C的朋友,那么A就是C的间接朋友,我们定义所谓的朋友圈就是由直系和间接朋友所组成的群体。N的范围为 [1,200].

例子 1:

输入:

3
1 1 0
1 1 0
0 0 1
输出: 2

解释:第0个和第1个学生是直系朋友,所以记为1个朋友圈。第2个学生他没什么朋友也要算一个朋友圈,所以结果为2.

例子 2:

输入:

3
1 1 0
1 1 1
0 1 1
输出: 1

解释:第0个和第1个学生是直系朋友,第1和第2个也是,所以第0和第2个学生是间接朋友,三个学生都在同个朋友圈里,返回1.

题目思路:这里把输入看成一个矩阵,朋友关系就是一个无向图的邻接矩阵,求有几个朋友圈就是求一个无向图中有几个连通分量
那么就有方法:1.DFS 2.并查集
这里给出并查集的做法

int to19_3_find(int x, int pre[]){
    // 返回根节点,并进行压缩路径
    int p=x, temp;
    while(x!=pre[x]){
        pre[x] = pre[pre[x]];
        x=pre[x];
    }
    return x;
}

void to19_3(){
    // 并查集
    int n;
    cin>>n;
    int map[n][n], pre[n];
    // 输入邻接矩阵
    for(int i=0; i<n; i++){
        pre[i]=i;
        for(int j=0; j<n; j++){
            cin>>map[i][j]; 
        }
    }
    for(int i=0; i<n; i++){
        for(int j=i+1; j<n; j++){
            if(map[i][j] == 1){
                int a = to19_3_find(i, pre);
                int b = to19_3_find(j, pre);
                // 当遍历到一条顶点为i,j的边,其中并查集中顶点i,j的根节点不同
                // (即i,j此时属于不同的集合时,将两集合合并)
                if(a!=b){
                    pre[a] = b;
                }
            }
        }
    }
    int res=0;
    // 统计根节点没有改变过的值
    for(int i=0; i<n; i++){
        if(pre[i]==i){
            res++;
        }
    }
    cout<<res<<endl;
}```

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值