A-codeJan与恐怖分子--------牛客网

codeJan与恐怖分子
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

把Noland抽象成一个n∗m的方格矩阵,行从上到下为1∼n,列从左到右为1∼m。codeJan处在坐标为(R,C)方格上,codeJan可以观察到他所在的行和列的治安情况。有一个恐怖分子想要毁掉Noland,又不被codeJan观察到。恐怖分子手中有无穷多个可以每次炸毁边长为K∗K的区域。方格矩阵的每个方格的边长为1。炸毁的区域不能超过Noland(方格矩阵)的范围,同一块区域可以炸毁多次。恐怖分子至少需要多少颗炸弹才能炸毁除了codeJan所在的行列的其余所有区域?或者无法完成这个任务?

输入描述:

第一行是一个 T(T ≤ 1000) 代表测试组数。接下来 T 行,每行包含 5 个正整数 n, m,R, C,K,含义如上。

输出描述:

一共输出 T 行,每行输出一个数字。如果可以完成任务,输出需要的最少的炸弹数量;否则无法完成任务,输出 -1。
示例1

输入

3 
1 1 1 1 1 
2 2 1 1 1 
3 3 2 2 1

输出

0
1
4

说明

第一个样例,因为只有一个格子且被警察占领,所以不需要额外炸掉格子,所以答案是 0。
第二个样例,只需要炸掉 (2,2) 这个格子,所以需要 1 颗可以炸毁 1*1 的炸弹。
第三个样例,有四个格子需要炸毁,所以需要 4 颗 1*1 的炸弹。

备注:

 
     
1 ≤ n, m,K ≤ 2*10 6, 1 ≤ R ≤ n, 1 ≤ C ≤ m。

思路:分成四个部分,求出4个部分能否被覆盖。

#include <stdio.h>
#include <stdlib.h>
long long t,n,m,r,c,k;
long long NoLand(long long a,long long b)
{
    if(a == 0 || b == 0)
        return 0;
    if(k > a || k > b)
        return -1e12;
    return (((a+k-1)/k) * ((b+k-1)/k));
}
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld %lld %lld %lld %lld",&n,&m,&r,&c,&k);
        long long sum = 0;
        sum+=NoLand(r-1,c-1);
        sum+=NoLand(n-r,c-1);
        sum+=NoLand(r-1,m-c);
        sum+=NoLand(n-r,m-c);
        printf("%lld\n",sum>(-1) ? sum:-1);
        
    }
    return 0;
}

java

import java.util.Scanner;

public class Main {
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int t = sc.nextInt();
		long n,m,r,c,k;
		for (int i = 0; i < t; i++) {
			n = sc.nextInt();
			m = sc.nextInt();
			r = sc.nextInt();
			c = sc.nextInt();
			k = sc.nextInt();
			System.out.println(new Main().NoLand(n, m, r, c, k));
		}
	}
	public long NoLand(long n,long m,long r,long c,long k){
		long sum = 0;
        if( (r!=1 &&k >r)|| (r != n && k > (n-r)) ||  (k>(c)&& c!=1)  || (m!=c&&k > (m-c)) ) return -1;
		sum = (ans(r-1,c-1,k)+ans(r-1,m-c,k)+ans(n-r,c-1,k)+ans(n-r,m-c,k));
		return sum;
	}
	public long ans(long a,long b ,long k){
		if(a==0 || b==0) return 0;
		return (((a+k-1)/k) * ((b+k-1)/k));
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值