CCNU 2012.7.8 Problem F

Problem F
Description

话说喵呜没事喜欢玩耗纸玩偶,现在有一个棋盘,有n行m列,喵呜在会在上面摆耗纸玩偶,话说每一个格子最多摆一个,而且他不希望任意两个耗纸玩偶的欧几里得距离为2,问喵呜最多能摆几只耗纸玩偶。

假设第一只耗纸的位置在x1,y1,第二只耗纸的位置在x2,y2,那么这两只耗纸的欧几里得距离为

Input

第一行输入一个数T,表示测试数据个数,对于每个测试数据,输入两个数n,m(0<n,m<10^9)

Output

对于每个测试数据,输出一个数,表示最多摆几个耗纸玩偶。

Sample Input

3

3 2

3 3

8 5

Sample Output

4

5

20

Hint

下列摆法其中*表示该位置有耗纸玩偶,-表示该位置没有耗纸玩偶

第一组数据:

* * -

- * *

第二组数据:

* * -

- * *

- - *
题目

 对于欧几里得距离为1的情况,我们发现最优解是按照一个间隔一个的摆放的,那么对于一个row*col的棋盘,可行的方案数是 (row*col+1)/2

 那么对于此题,求欧几里得距离为2的情况,我们发现对于每四个方格,我们可以放四只耗子,那么对于这四只耗子作为一个整体的情况,我们就转换成欧几里得距离为1的那种情况了,但是对于这个四只耗子怎么取,则根据row和col分别奇偶的讨论,最后将4种奇偶情况的结果加起来。

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
long long solve(int row,int col)
{
    long long ans=(long long)row*col;
    return (ans+1)/2;
}
int main()
{
    freopen("F.in","r",stdin);
    freopen("F.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int row,col;
        scanf("%d%d",&row,&col);
        long long ans=solve((row+1)/2,(col+1)/2);
        ans+=solve(row/2,col/2);
        ans+=solve((row+1)/2,col/2);
        ans+=solve(row/2,(col+1)/2);
        printf("%lld\n",ans);
    }
    return 0;
}
View Code
20
757147 167851000
301413356 336971124
659598368 160567225
391749387 4890851
35766290 26239572
473038164 597006
3615544 326051436
392289610 118341522
170427798 37215528
675016433 168544290
683447133 950090226
82426872 116752251
194041604 706221268
69909134 257655783
84970743 21417562
37379060 40873980
8670528 80835680
436291072 653352030
106923810 374079500
466701606 86546364
F.in
63543940548500
50783798679966072
52954939782144400
957993940579169
469246070813940
141203311068492
589426656560592
23212074756093212
3171280244223672
56885082719158786
324668220525511030
4811761424444436
68518153810816936
9006246329810962
909933078194284
763915475429400
350444013419520
142525828781038080
19999002691447500
20195663536130292
F.out
原文地址:https://www.cnblogs.com/overflow/p/3134555.html