注释非常详细
好几个坐标的运算要多画画图
要注意第64行有一个非常简单的剪枝
然而没有就少了20分
如下贴代码:
代码:
#include<cstdio> #include<iostream>//其实你也可以考虑用万能但本人不太习惯用,吱吱 using namespace std; int n, m, ans = 250000 + 2, num; struct Node{ int x, y; }; struct Node node[51]; struct Squre{ int ax, ay; //↙左下角(ax, ay) //↘右下角(bx, ay) int bx, by; //↗右上角(bx, by) //↖左上角(ax, by) }; struct Squre s[7]; bool is_involve(int i, int j){ //判断点i是否在矩形j内 if (node[i].x < s[j].ax || node[i].x > s[j].bx) return false; if (node[i].y < s[j].ay || node[i].y > s[j].by) return false; return true; } bool judge(int j){ //判断新矩形j是否影响其他矩形 for (int i = 1; i <= num; i++){ if (i == j) continue; //方法:只要有某个矩形中有一个点在矩形j内 则有重叠 if (s[i].ax >= s[j].ax && s[i].ay >=s[j].ay && s[i].ax <= s[j].bx && s[i].ay <= s[j].by) return false; if (s[i].bx >= s[j].ax && s[i].ay >=s[j].ay && s[i].bx <= s[j].bx && s[i].ay <= s[j].by) return false; if (s[i].ax >= s[j].ax && s[i].by >=s[j].ay && s[i].ax <= s[j].bx && s[i].by <= s[j].by) return false; if (s[i].bx >= s[j].ax && s[i].by >=s[j].ay && s[i].bx <= s[j].bx && s[i].by <= s[j].by) return false; } return true; } int _s(int i){ //计算第i个矩形的面积 return (s[i].by - s[i].ay) * (s[i].bx - s[i].ax); } int sum(){ //计算第i个矩形的面积 int _sum = 0; for (int i = 1; i <= num; i++) _sum = _sum + _s(i); return _sum; } void dfs(int i){ //对于每一个点(node[i].x, node[i].y) //* if (i > n){ ans = min(ans, sum()); // cout << endl; // for (int i = 1; i <= num; i++){ // cout << s[i].ax << ", " << s[i].ay << " - " << s[i].bx << ", " << s[i].by << endl; // cout << " + " << _s(i) << endl; // } // cout << sum() << endl; return ; } if (sum() >= ans) return ; //Cut //1°加入前面的组 for (int j = 1; j <= num; j++){ //1°- 1′可直接加入 if (is_involve(i, j)){ //如果点i在矩形j内 dfs(i + 1); } else{ //1°- 2′不可直接加入 要扩大原有矩形 int preax = s[j].ax, preay = s[j].ay, prebx = s[j].bx, preby = s[j].by; s[j].ax = min(node[i].x, s[j].ax); s[j].ay = min(node[i].y, s[j].ay); s[j].bx = max(node[i].x, s[j].bx); s[j].by = max(node[i].y, s[j].by); if (!judge(j)){ //1°- 2′- 1″扩大原有矩形后 与其他矩形重合 s[j].ax = preax; s[j].ay = preay; s[j].bx = prebx; s[j].by = preby; //还原 continue; } //1°- 2′- 2″扩大原有矩形后 不影响其他矩形 dfs(i + 1); s[j].ax = preax; s[j].ay = preay; s[j].bx = prebx; s[j].by = preby; //还原 } } //2°自成一组 if (num < m){ num++; s[num].ax = node[i].x; s[num].bx = node[i].x; s[num].ay = node[i].y; s[num].by = node[i].y; dfs(i + 1); num--; //还原 } return ; } int main(){ scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d%d", &node[i].x, &node[i].y); dfs(1); cout << ans;//最后是将答案输出,这个不多说 return 0;//程序到达了终点,程序:“可以睡觉啦” }