棋盘 最小移出步数

There is a rectangular chessboard containing N*M cells, each of which either has one coin or nothing.

You can move all coins together in one direction(such as up, down, left, and right), but each time you can move these coins by only one cell.

If any coins fall out of the chessboard, they must be thrown away.

If it is required to keep K coins on the board, what is the minimum moves you have to take?

Output -1 if you can no meet this requirement.

输入描述:
The first line of the input are two positive integers n, representing the size of the board.

For the next n line(s), each line has m numbers of characters, with ‘o’ indicating a coin, ‘.’ indicates an empty grid.

The last line is a positive integer k, indicating the number of coins to be retained.

输入描述:
30% small input: 1 <= n, m <= 5, 0 <= k <= 25
40% medium input: 1 <= n, m <= 10, 0 <= k <= 100
30% medium input: 1 <= n, m <= 100, 0 <= k <= 1000

输出描述:
Output
an integer that represents the number of moves, no solution output -1

示例

输入
3 4
.o..
oooo
..o.
3

输出
2

java代码

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        in.nextLine();
        int[][] cnt = new int[n][m + 1];
        for (int i = 0; i < n; ++i) {
            String s = in.nextLine();
            for (int j = 0; j < m; ++j) {
                int t  = s.charAt(j) == 'o' ? 1 : 0;
                cnt[i][j + 1] = cnt[i][j] + t;
            }
        }
        int k = in.nextInt();
        in.close();
        int ans = -1;
        for (int left = 0; left < m; ++left) {
            for (int right = left + 1; right <= m; ++right) {
                int top = 0, bottom = 1, sum = cnt[top][right] - cnt[top][left];
                while (bottom <= n) {
                    if (sum == k) {
                        int cost = Math.min(left, m - right) * 2 + Math.max(left, m - right)
                                + Math.min(top, n - bottom) * 2 + Math.max(top, n - bottom);
//                      System.out.println(top + " " + bottom + " " + left + " " + right + " " + cost);
                        if (ans == -1 || cost < ans) {
                            ans = cost;
                        }
                        if (bottom == n) {
                            break;
                        }
                        sum += cnt[bottom][right] - cnt[bottom][left];
                        bottom++;
                    } else if (sum > k) {
                        sum -= cnt[top][right] - cnt[top][left];
                        top++;
                    } else if (bottom < n) { // sum < k
                        sum += cnt[bottom][right] - cnt[bottom][left];
                        bottom++;
                    } else { // sum < k && bottom == n
                        break;
                    }
                }
            }
        }
        System.out.println(ans);
    }
}
/************
3 4 
.o..
oooo
..o.
3
 ************/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值