网络流 方阵移动

Description

操场可以看成一个平面直角坐标系,在操场上有n*n个同学。你希望将这n*n个同学排成一个间距为1的n*n的方阵,并且要求方阵的左边界在y轴上。每个同学在初始格点(xi,yi)上,可以移动到任何一个格点(xi’,yi’),耗费的体力值为(|xi-xi’|+|yi-yi’|)^p,xi,yi是整数,p是正整数。现在你想知道,将这n*n同学移动成符合要求的方阵的情况下,总共耗费的体力值最小是多少。

Input

每个测试点包含多组测试数据,第一行一个正整数t,表示有t组测试数据。接下来有t个部分。每个部分第一行两个正整数n,p,含义如上所述,接下来n*n行,每行两个整数,表示每个同学的坐标。

Output

输出t行,每行一个整数,表示这一组测试数据的总共耗费最小体力值。

Sample Input

2

2 1

0 2

2 1

3 1

3 2

2 2

0 0

0 1

1 0

2 2

Sample Output

6

4

【样例说明】

Case #1:

(2,1) -> (0,1)  cost 2

(3,1) -> (1,1)  cost 2

(3,2) -> (1,2)  cost 2

Case #2:

(2,2) - > (1,1)  cost 4

 

Data Constraint

 

真好呢,突然换题搞得只有三个小时考

刚看时一脸懵逼

只会3,4,7,8的40分

暴力枚举方阵位置,跑费用流

接下来思考特性

感性(dabiao)发现当方阵位置变化,其最优值,是一个单峰函数(联想绝对值方程)

单峰函数可以三分

于是这就是一道三分费用流模板题。。。

好的,我可以为你提供一个简单的Java代码示例,用于实现循环位移方阵并可以控制移动方向和移动位数。以下是示例代码: ```java import java.util.Arrays; public class MatrixShift { public static void main(String[] args) { int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; // 初始化一个 3x3 的方阵 int direction = 1; // 移动方向,1 表示向右,2 表示向下,3 表示向左,4 表示向上 int steps = 2; // 移动位数 System.out.println("移动前的方阵:"); printMatrix(matrix); shiftMatrix(matrix, direction, steps); // 调用移动方法 System.out.println("移动后的方阵:"); printMatrix(matrix); } public static void shiftMatrix(int[][] matrix, int direction, int steps) { int n = matrix.length; // 获取方阵的行数 int[] temp; // 定义一个临时数组 switch (direction) { case 1: // 向右移动 for (int i = 0; i < n; i++) { temp = Arrays.copyOf(matrix[i], n); // 复制当前行 for (int j = 0; j < n; j++) { matrix[i][(j + steps) % n] = temp[j]; // 将当前行向右移动 steps 位 } } break; case 2: // 向下移动 for (int j = 0; j < n; j++) { temp = new int[n]; for (int i = 0; i < n; i++) { temp[(i + steps) % n] = matrix[i][j]; // 将当前列向下移动 steps 位 } matrix[0][j] = temp[0]; matrix[1][j] = temp[1]; matrix[2][j] = temp[2]; // 将移动后的列复制回原方阵 } break; case 3: // 向左移动 for (int i = 0; i < n; i++) { temp = Arrays.copyOf(matrix[i], n); for (int j = 0; j < n; j++) { matrix[i][(j - steps + n) % n] = temp[j]; // 将当前行向左移动 steps 位 } } break; case 4: // 向上移动 for (int j = 0; j < n; j++) { temp = new int[n]; for (int i = 0; i < n; i++) { temp[(i - steps + n) % n] = matrix[i][j]; // 将当前列向上移动 steps 位 } matrix[0][j] = temp[0]; matrix[1][j] = temp[1]; matrix[2][j] = temp[2]; } break; default: System.out.println("无效的移动方向!"); } } public static void printMatrix(int[][] matrix) { for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[i].length; j++) { System.out.print(matrix[i][j] + "\t"); } System.out.println(); } } } ``` 在上面的示例代码中,我们定义了一个 `shiftMatrix` 方法,用于实现方阵的循环位移。该方法接受三个参数,分别是要移动方阵移动方向和移动位数。其中,移动方向和移动位数由调用方法的代码传入。 在方法内部,我们使用了 `switch` 语句来根据移动方向的不同,分别进行方阵移动操作。具体来说,向右移动时,我们使用了 `Arrays.copyOf` 方法来复制当前行,并将复制后的行向右移动 `steps` 位;向下移动时,我们则需要遍历每一列,并将当前列向下移动 `steps` 位;向左移动和向上移动的操作类似,只需要将向右移动和向下移动的代码进行适当的修改即可。 在调用 `shiftMatrix` 方法之后,我们还定义了一个 `printMatrix` 方法,用于输出移动前和移动后的方阵。该方法接受一个二维数组作为参数,遍历数组并依次输出每个元素的值。 希望这个示例代码可以帮助你实现循环位移方阵并可以控制移动方向和移动位数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值