【leetcode_1601】【困难】maximum-number-of-achievable-transfer-requests / 最多可达成的换楼请求数目

URL

链接:https://leetcode-cn.com/problems/maximum-number-of-achievable-transfer-requests/


题目

[截图]
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


分析

[截图]


源码

#include <stdio.h> 
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

int maximum_requests(int n, int **requesets, int requeset_size, int *requeset_col_size){

    int * delta = (int *)malloc(sizeof(int) * n);  	// n栋楼
    int ans = 0, m = requeset_size;					// m个请求
    for (int  mask = 0; mask < (1 << m); ++mask){
        int cnt = __builtin_popcount(mask);  		// GCC 内建函数 统计mask中1的个数, 平台不通用,不一定可移植
        if( cnt <= ans){  							// 如果当前可响应的请求 <= 已经响应过的请求个数(现在楼层变化的数量) ,则判断下一个请求是否可行
            continue;
        }
        memset(delta, 0, sizeof(int) * n);   		// n栋楼的变化数量δ 
        for (int i = 0; i < m; i++){				// 遍历m个请求
            if (mask & (1 << i)){					// 如果第i个请求被选中,则from楼增加的人数++,to楼的人数--
                ++delta[requesets[i][0]];
                --delta[requesets[i][1]];
            }
        }
        
        bool flag = true;
        /* 遍历n栋楼的变化是否==0,不为0则表示响应后无法满足楼层变化相同的要求,也即无法响应这次请求 */
        for (int i = 0; i < n; ++i){
            if (delta[i] != 0){
                flag = false;
                break;
            }
        }
		/* 如果请求可被满足,则可响应请求数ans++ */
        if (flag){
            ans = cnt;
        }
    }
    return ans;
}

int main()
{
#ifdef TEST_1
    int n = 5; 
    int **requesets = (int **)malloc(sizeof(int *) * 6);
    int arr[6][2] = {{0,1},{1,0},{0,1},{1,2},{2,0},{3,4}};

    for (int i = 0; i < 6; i++){
        requesets[i] = (int *)malloc(sizeof(int) * 2);
    }

    for (int i = 0; i < 6; i++){
        for (int j = 0; j < 2; j++){
            requesets[i][j] = arr[i][j];
        }
    }

    int ret = maximum_requests(n, requesets, 6, NULL);
    printf("ret : 5 = %d ?\n",ret);

    for (int i = 0; i < 6; i++){
        free(requesets[i]);
    }
    free(requesets);

	return 0;
#else
    int n = 3; 
    int **requesets = (int **)malloc(sizeof(int *) * 6);
    int arr[3][2] = {{0,0},{1,2},{2,1}};

    for (int i = 0; i < 3; i++){
        requesets[i] = (int *)malloc(sizeof(int) * 2);
    }

    for (int i = 0; i < 3; i++){
        for (int j = 0; j < 2; j++){
            requesets[i][j] = arr[i][j];
        }
    }

    int ret = maximum_requests(n, requesets, 3, NULL);
    printf("ret : 3 = %d ?\n",ret);

    for (int i = 0; i < 3; i++){
        free(requesets[i]);
    }
    free(requesets);

	return 0;
#endif
}


源码概述

  1. 请求m长的二进制数mask存储所有的请求个数,用bit位表示第i次请求。主要是m主要用于控制遍历响应次数
  2. 用delta[楼层号]表示第i次请求后楼层的变化值,为0则表示这次请求后满足“每个楼转入数=转出数”
  3. 遍历上述delta[]是否为0,可被满足则进入下一次请求,即mask下一bit+1,总共m个bit位

小结

  1. 用到了一个GCC的内建函数__builtin_popcount(mask),判断bit为1的个数。学习到了,用二进制表示请求个数,配合内建函数。
  2. 一个delta[]表示响应每次请求后各个楼层变化数量,每次请求可调整两栋楼的变化数量,这也是注意点。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

过得精彩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值