题意:小孩要去取快件,有一排序号从 1 到 n 的柜子,相邻的柜子距离是 1,出入口在编号为 1 的柜子处。每次去快递前都要先去编号为 k 的柜子处输入口令来打开其他柜门(保证这个柜子不放东西并且每个柜子只放一个快件)再前往打开的柜门处取快件。拿完最后一个快件小孩就走向出入口。现在有 m 个快件要拿,给出 k 的位置,让你找出短的取完所有快件的路的长度
思路:除去去取第一个快件需要先走到 K 号柜以及取最后一个快件不用折返,其他取快件的操作可以分组看成快件与 K 号柜之间的折返操作,这些走过的距离是固定的,那么最短路就取决于在最后一次取快件的路径长短(因为最后一个快件的选择直接决定了是否需要走多余的折返路径)。
以下面为例:3 号柜相当于 K 号柜,那么选择一号柜的快件(距离出口最近的)作为最后一次取是最优解的,其他的快件都看成和 3 号柜之间的折返操作,而最后一次取快件在 K 号柜左边,和之前没算上的距离正好是起点和 3 号柜之间距离的折返,但是注意若是最后一次取快件的柜子还是在 K 号柜的右边,那么还是相当于多走了一个和 K 号柜之间距离的折返。所以真正能够缩小走过的距离的情况是最后一次取快件的柜子在 K 号柜左侧
综上:对于每个快件的柜子,都加和其和 K 号柜之间距离的二倍,再加上起点和 K 号柜之间距离的二倍。然后若是最近的一个柜子编号比 K 号柜小那么结果再减去其和 K 号柜之间距离的二倍。
题意:有一个 nxn 的矩阵 A 和一个 3x3 的矩阵 K,均为非负矩阵,并且 K 是一个和为 1 的分数矩阵。定义一个操作,对于矩阵 A,用矩阵 K 对 A 中的每个元素进行卷积操作——K 的左上角遍历 A 中每个元素,每一次覆盖对 A 中 3x3 范围内(范围不够的在 A 的边缘补上足够多的 0)的矩阵在 K 的作用下作带权求和运算。现在将矩阵 K 固定,拿 C 套娃无限次,求最终得到的矩阵
#include<bits/stdc++.h> constint maxn = 55; int A[maxn][maxn]; int K1[4][4];
signedmain(){ int T;scanf("%d", &T); while (T--){ int n;scanf("%d", &n); //input matrix A and K' for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) scanf("%d", &A[i][j]); for (int i = 1; i <= 3; ++i) for (int j = 1; j <= 3; ++j) scanf("%d", &K1[i][j]); //solve int sum = 0; for (int i = 1; i <= 3; ++i) for (int j = 1; j <= 3; ++j) sum += K1[i][j]; bool full_zero = true;//判断是否会最终矩阵趋于0 if (K1[1][1] == sum) //K[1][1] == 1 full_zero = false; //output for (int i = 1; i <= n; ++i){ bool first = true; for (int j = 1; j <= n; ++j) { if (!first) printf(" "); first = false; if (full_zero) printf("0"); else printf("%d", A[i][j]); } printf("\n"); } } return0; }