BestCoder17 1001.Chessboard(hdu 5100) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5100

题目意思:有一个 n * n 的棋盘,需要用 k * 1 的瓷砖去覆盖,问最大覆盖面积是多少。

  比赛时不会做.............

hdu 题解:

首先,若n<k,则棋盘连一个1×k的矩形都放不下,输出0。

我们只需要考虑n≥k的情况。将棋盘类似于黑白染色,按(i+j)模k划分等价类,给每个格子标一个号。

标号之后,会注意到每条从左下到右上的斜线数字都是相同的,那么对于s×s的格子,其内部数字有且恰好有2s−1种,所以当s<=k2的时候,内部数字有floor(k2)∗2−1<k种,所以不能有更佳的方案。

从而证明最优的方案一定是仅剩下一个s×s的正方形区域没有被覆盖到,其中s ≤k2。

而令l = n mod k之后,根据l大小的不同,可以构造出中心为l×l或(k−l)×(k−l)的风车形图案,又通过上面证明这个l(或k−l)就是之前的s,所以是最优的。

所以令l = n mod k,如果l≤k2,最多可覆盖的格子数即为n2−l2,否则为n2−(k−l)2,显然这样的方案是可以构造出来的(风车形)。

其实我觉得这个题解更好看,热烈推荐下面这个:

    http://www.matrix67.com/blog/archives/5900

 1 #include<iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cmath>
 6 using namespace std;
 7
 8 int main()
 9 {
10     int T, n, k;
11     while (scanf("%d", &T) != EOF)
12     {
13         while (T--)
14         {
15             scanf("%d%d", &n, &k);
16             if (n < k)
17                 printf("0\n");
18             else
19             {
20                 int area = n * n;
21                 int remain = n % k;
22                 printf("%d\n", remain <= k/2 ? area-remain*remain : area-(k-remain)*(k-remain));
23             }
24         }
25     }
26     return 0;
27 }

时间: 2024-08-07 03:14:17

BestCoder17 1001.Chessboard(hdu 5100) 解题报告的相关文章

BestCoder17 1002.Select(hdu 5101) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5101 题目意思:给出 n 个 classes 和 Dudu 的 IQ(为k),每个classes 都有相应的人,每个人又有相应的IQ.现在要求从这些classes挑选两个人,满足IQ之和 > k,不过要满足这两个人不能来自同一个class的. 解题思路不难想出,直接所有人两两之和 > k - 同一个class 两两之和 > k  就是答案了. 不过很容易超时!!!! 用二分就可以过了.二分有

BestCoder8 1001.Summary(hdu 4989) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4989 题目意思:给出 n 个数,然后将这些数两两相加,得到 n*(n-1) /2 对和,把重复的和去掉,最后相加起来. 用STL中的set可以好方便的做出来,因为 insert 的时候它会自动去除重复的.记得要用 long long 或 int64,因为 -1000000000 <= ai <= 1000000000 ! 1 #include <iostream> 2 #include

hdu 2112 HDU Today 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2112 题目意思:又是求最短路的,不过结合埋字符串来考查. 受之前1004 Let the Balloon Rise 学到用map 的解法做之后,有点蠢蠢欲动,当时见到要用字典树做有点吓坏了(之前看过下,非一般难理解,所以暂时放下了).于是,死就死吧,硬住头皮用map做,反反复复修改终于过了. 首先是memory limit exceeded,因为无读清题目意思,直接开10000 * 10000的数组

BestCoder10 1001 Revenge of GCD(hdu 5019) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5019 题目意思:给出 X 和 Y,求出 第 K 个 X 和 Y 的最大公约数. 例如8 16,它们的公约数依次为1 2 4 8,那么第 3 个 GCD(X, Y) = 2,也就是从后往前数第3个公共因子. TLE思路:求出 X 的所有因子(从小到大开始存储),再从后往前枚举这些因子,检查是否也为 Y 的因子,统计到第 K 个数就是答案了......以为可以顺利通过,原来数据量还是非常大滴!!! 正确

BestCoder10 1001 Revenge of Fibonacci(hdu 5018) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5018 题目意思:给出在 new Fibonacci 中最先的两个数 A 和 B(也就是f[1] = A, f[2] = B),通过这条式子f[n] = f[n-1] + f[n-2],问 C 是否在这条 new Fibonacci sequence 内.(1 <= A, B, C <= 1 000 000 000) 首先,要想到 C 有可能是 A 或者 B,这种情况也是属于在这个序列范围内的. 还

BestCoder24 1001.Sum Sum Sum(hdu 5150) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5150 题目意思:就是直接求素数. 不过 n = 1,也属于答案范围!!只能说,一失足成千古恨啊----- 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 1

BestCoder18 1001.Alexandra and Prime Numbers(hdu 5108) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5108 题目意思:给出一个数正整数 N,N <= 1e9,现在需要找出一个最少的正整数 M,使得 N/M 是素数.如果找不到就输出0. 一开始有想过将所有 <= 1e9 的素数求出来的,不过绝对超时就放弃了:然后就开始从题目中挖掘简便的处理方法.受到求素数的方法启发,枚举的因子 i 如果在 i * i <= N 之内都没有找到符合条件的素数,那么那些 > N 的因子就更不可能了.于是时间

BestCoder12 1001.So easy(hdu 5058) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5058 (格式有点问题,为了方便阅读---整个复制下来吧) 题目意思:给出两个长度都为 n 的集合你,问这两个集合是否相等. 其实思路非常容易想到,就是去重后判断嘛---我用到了set 来做.不过有个小细节!!! 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstr

BestCoder3 1001 Task schedule(hdu 4907) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4907 题目意思:给出工作表上的 n 个任务,第 i 个任务需要 ti 这么长的时间(持续时间是ti ~ ti+1)来完成.有m 个询问,每个询问是一个数字q,表示q 时间上有一个非 n 个任务之外的任务请求.机器是按照工作表的任务时间来执行的,如果有空档时间,它会执行工作表之外的任务请求. 直接做,果断超时!1e5 * 2e5 !!!(m次询问+q次遍历 的最坏情况) 二分解决之----一开始我不是