小美的平衡矩阵(前缀和例题 -- 美团笔试编程题)
创始人
2024-11-06 08:10:03
0

        2024美团春招,被这一题给难住了 美团校招笔试真题_Java工程师、C++工程师_牛客网

题目:

        

        

解答:

        这道题的关键点就是要计算出以某一点为矩阵右下角时,1的个数

        我一开始是想着遍历,以某一点为起点(矩阵左上角),遍历i*i的矩阵,但是要用五层循环,超时了。然后又想着将之前的矩阵的结果保留下来,这样计算新矩阵时就能大大减少遍历次数,只用查看前面矩阵的结果来推算出当前矩阵的结果,可是我用的是动态规划,会计算左边和上边的值,这有一个问题,就是左上角对角线位置的值会被计算两次,因为上边的左边算了一次,左边的上边也算了一次。后来看了别人的代码,发现只要动态规划时只计算一边,即上边或者左边的值,另一个值在本次循环的时候单独计算就能解决了,这就是前缀和,用于在数组或矩阵中快速计算某个区间内的元素和。

        这道题的思路就是,用前缀和计算出从左上角[0,0]到右下角[x,y]这个范围内的矩阵的值,这样,如果想要计算以[x,y]为终点的 i*i 的矩阵的值,就只需要用[x,y]的值减去[x-i,y]和[x,y-1]的值再加上以[x-i,y]为终点、以[x,y-1]为终点这两个矩阵的重合部分(刚刚被减了两次)就行了。

        之后再对结果进行判断,就能知道以[x,y]为终点的 i*i 的矩阵是否是平衡矩阵。如果是则记录。

        这种方法只有三层循环,大大降低了时间复杂度。

int main() {     int n = 4;     vector matrix(n);     matrix[0] = "1010";     matrix[1] = "0101";     matrix[2] = "1100";     matrix[3] = "0011";       vector> dp(n + 1, vector(n + 1));      for (int i = 0; i < n; i++) {         int sum = 0;         //动态规划,但是如果又加上面又加左边会导致对角线左上方被算两次,所以只动态规划算上面,左边的单独在本趟算         for (int j = 0; j < n; j++) {             if (matrix[i][j] == '1') sum++;             dp[i + 1][j + 1] = sum + dp[i][j + 1];         }     }       vector res(n + 1);      //i*i的矩阵     for (int i = 1; i <= n; i++) {         //当矩阵内元素个数为奇数,一定不平衡         //一个奇数的平方一定是奇数         if (i % 2 != 0) {             res[i] = 0;             continue;         }         //以[x,y]为起点的矩阵,其右下角值=以其右下角为终点的矩阵的1的个数         //x+i-1 -- i为2时,计算x和x+1位置,那么包括x位置在内,总共i个位置需要合法,也就是接下来的i-1个位置需要合法         for (int x = 1; x + i - 1 <= n; x++) {             for (int y = 1; y + i - 1 <= n; y++) {                 //[x+i-1][y+i-1]的值是从[1,1]到[x+i-1][y+i-1]的值                 //  那么如果要计算以[x+i-1][y+i-1]为终点的i*i矩阵1的值,需要减去以[x+i-1][y-1]为终点的矩阵2的值和以[x-1][y+i-1]为终点的矩阵3的值                 //  这还不够,矩阵2和矩阵3有一个重合的区域,如果只是减的话,重合的区域会被减两次,所以减完后还需要加上一个重合的区域的值,也就是以[x-1][y-1]为终点的矩阵4的值                 int val = dp[x + i - 1][y + i - 1] - dp[x + i - 1][y - 1] - dp[x - 1][y + i - 1] + dp[x - 1][y - 1];                 if (val == (i * i) / 2) {                     res[i]++;                 }             }         }     }     for (int i = 1; i <= n; i++) {         cout << res[i] << endl;     }       return 0; }

相关内容

热门资讯

wepoke辅助挂(透视)we... wepoke辅助挂(透视)wepower德州辅助器(详细辅助可靠技巧)都是真的是有挂(黑科技计算辅助...
微扑克辅助挂(微扑克)微扑克系... 微扑克辅助挂(微扑克)微扑克系统机制(透视)好像真的是有挂(详细辅助黑科技教程)1、玩家可以在微扑克...
wepower辅助器(透视)w... wepower辅助器(透视)wepokeapp下载教程(详细辅助扑克教程)切实存在有挂(教你计算辅助...
微扑克游戏辅助器(微扑克)微扑... 微扑克游戏辅助器(微扑克)微扑克wpk(透视)总是真的是有挂(详细辅助安装教程)1、微扑克游戏辅助器...
WePoKe透明挂(透视)wo... WePoKe透明挂(透视)wopoker外挂(详细辅助安装教程)总是有挂(玩家插件)1、WePoKe...
微扑克ai辅助工具(微扑克)微... 微扑克ai辅助工具(微扑克)微扑克辅助是什么(透视)果然存在有挂(详细辅助解密教程);微扑克ai辅助...
wepoke的确有挂(透视)w... wepoke的确有挂(透视)wepoke挂真的假的(详细辅助插件教程)好像真的是有挂(教你辅助器)1...
微扑克ai辅助工具(微扑克)微... 微扑克ai辅助工具(微扑克)微扑克俱乐部管理(透视)其实存在有挂(详细辅助揭秘教程);1、微扑克ai...
wepok软件透明挂(透视)w... wepok软件透明挂(透视)wepoke智能ai(详细辅助攻略方法)一直有挂(详细计算辅助)1、进入...
微扑克系统发牌规律(微扑克)微... 微扑克系统发牌规律(微扑克)微扑克辅助器下载(透视)竟然真的是有挂(详细辅助辅助教程);在进入微扑克...