Square Garden UVA

来源:互联网 发布:游戏代练网站源码 编辑:程序博客网 时间:2024/05/21 11:51

有点复杂的一道题目,对于任意的一个正方形网格,首先考虑当要填充的正方形个数较小的时候,填充n个正方形,产生的新的边数即为4*n;如果填充的正方形的个数太多的时候,我们就首先计算出填充了n个正方形之后有多少个未填充空格,假设为k个,同时假设当前正方形上下去掉一行左右去掉一列之后最优的填充策略是填充t个,现在就利用一个逆向思维,假设当前是填入k个空格到中心的那个正方形,如果k<=t,那么填充了k个就会新产生4*k条边;如果上述两种情况都不满足,那么就将之前中心的正方形填入t个空格,这个时候还会多出k-t个空格,那么这个时候分析就会发现每条边中会存在一些正方形,填入空格后会使边数增加2,这样的正方形的个数是L/2-1(每条边),将这些正方形填入;同时如果当前判断的正方形的边数为奇数,那么中心的正方形的边数也为奇数个,那么这个时候还要考虑对称的情况,也就是之前填入空格的方形不进行填入,未填入的进行填入,然后再计算一次,取二者的最大值即可,好了,废话讲了这么多,具体代码如下:

#include<iostream>#include<vector>#include<string>#include<set>#include<stack>#include<queue>#include<map>#include<algorithm>#include<cmath>#include<iomanip>#include<cstring>#include<sstream>#include<cstdio>#include<deque>#include<functional>using namespace std;typedef long long LL;LL L, N;int main(){while (cin >> L >> N){if (L == 0 && N == 0) break;LL best = (L*L + 1) / 2;LL remain = L*L - N;LL center_best = ((L - 2)*(L - 2) + 1) / 2;LL res;if (N <= best){res = 4 * N;}else if (remain <= center_best){res = 4 * (L + remain);}else{res = 4 * (L + center_best) +2 * min(remain-center_best, 4 * (L / 2 - 1));LL other = (L - 2)*(L - 2) - center_best;if (L % 2){res = max(res, 4 * (L + other) + 2 * (remain-other));}}cout << res << endl;}return 0;}