51nod 1487:占领资源 很好玩很痛苦
2016-02-18 13:37
162 查看
1487 占领资源
题目来源: TopCoder
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
收藏
关注
有一个矩形区域被划分为N行M列的网格,每个格子里有一定数量的资源并记录在矩阵val中,坐标(x,y)位置上资源量为val[x][y],其val中每个元素的值为0~9的整数。如果你在某个网格(a,b)上造一座保护塔,那么你可以占领K个网格中的资源,这K个格子分别是(a+dx[1],b+dy[1]),(a+dx[2],b+dy[2]),...,(a+dx[K],b+dy[K]),注意(a,b)这格本身可能未必会被占领。现在你能建造不超过2个塔,问最多能占领多少资源?一个网格被多个塔占领时其资源只计算一次。另外如果计算的位置(a+dx[i],b+dy[i])在网格外,则不贡献任何资源。
Input
Output
Input示例
Output示例
这个题自己想了很久。。。困于时间和空间。。。一直想枚举两个点,但这样复杂度就超时了。然后如果对每一个点计算其重叠,这样的话空间又会爆。。。
后来和丁神讨论题解之后,终于在第二天才敲出来。。。
这个题的解题思路真的很服。。。
任何一个点不会与超过k^2个点有公共交点。
因此不妨对每个点单独处理这k^2个特殊位置,而其他位置直接取最大值即可。
代码:
题目来源: TopCoder
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
收藏
关注
有一个矩形区域被划分为N行M列的网格,每个格子里有一定数量的资源并记录在矩阵val中,坐标(x,y)位置上资源量为val[x][y],其val中每个元素的值为0~9的整数。如果你在某个网格(a,b)上造一座保护塔,那么你可以占领K个网格中的资源,这K个格子分别是(a+dx[1],b+dy[1]),(a+dx[2],b+dy[2]),...,(a+dx[K],b+dy[K]),注意(a,b)这格本身可能未必会被占领。现在你能建造不超过2个塔,问最多能占领多少资源?一个网格被多个塔占领时其资源只计算一次。另外如果计算的位置(a+dx[i],b+dy[i])在网格外,则不贡献任何资源。
Input
多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5 每组测试数据有相同的结构构成: 每组数据第一行三个整数N,M,K,其中2<=N,M<=100,1<=K<=10。 之后会有N行,每行M个元素,表示val矩阵。每个元素为0~9,占一个字符,元素间没空格。 再接下来有K行,每行两个整数dx[i]与dy[i],其中-(N-1)<=dx[i]<=N-1,-(M-1)<=dy[i]<=(M-1).
Output
每组数据一行输出,即可占领的最大资源总量。
Input示例
3 2 2 2 11 11 0 0 0 1 2 2 2 11 11 0 0 1 1 2 2 1 15 61 0 0
Output示例
4 3 11
这个题自己想了很久。。。困于时间和空间。。。一直想枚举两个点,但这样复杂度就超时了。然后如果对每一个点计算其重叠,这样的话空间又会爆。。。
后来和丁神讨论题解之后,终于在第二天才敲出来。。。
这个题的解题思路真的很服。。。
任何一个点不会与超过k^2个点有公共交点。
因此不妨对每个点单独处理这k^2个特殊位置,而其他位置直接取最大值即可。
代码:
#pragma warning(disable:4996) #include <iostream> #include <functional> #include <algorithm> #include <cstring> #include <vector> #include <string> #include <cstdio> #include <cmath> #include <queue> #include <stack> #include <deque> #include <ctime>; #include <set> #include <map> using namespace std; typedef long long ll; #define INF 0x3fffffff #define rep(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) const ll mod = 1e9 + 7; const int maxn = 105; int has[maxn][maxn][105]; int con[maxn][maxn][105]; int sz[maxn][maxn],ha_sz[maxn][maxn]; map<pair<int, int>, int>res; int n, m, k, ans; int dx[maxn], dy[maxn], val[maxn][maxn]; int flag_cal[100200]; struct no { int id; int val; }node[100200], node2[100200]; bool cmp(no n1, no n2) { return n1.val > n2.val; } void input() { char tmpc; int i, j; scanf("%d%d%d", &n, &m, &k); scanf("%c", &tmpc); memset(node, 0, sizeof(node)); memset(node2, 0, sizeof(node2)); memset(sz, 0, sizeof(sz)); memset(ha_sz, 0, sizeof(ha_sz)); memset(flag_cal, 0, sizeof(flag_cal)); for (i = 1; i <= n; i++) { for (j = 1; j <= m; j++) { scanf("%c", &tmpc); val[i][j] = tmpc - '0'; int d = (i - 1)*m + j; node[d].id = d; } scanf("%c", &tmpc); } for (i = 1; i <= k; i++) { scanf("%d%d", &dx[i], &dy[i]); } } void solve() { int i, j, h, g; for (i = 1; i <= n; i++) { for (j = 1; j <= m; j++) { for (h = 1; h <= k; h++) { if (i + dx[h] >= 1 && i + dx[h] <= n&&j + dy[h] >= 1 && j + dy[h] <= m) { int pos_x = i + dx[h]; int pos_y = j + dy[h]; int point_flag = (i - 1)*m + j; sz[pos_x][pos_y]++; con[pos_x][pos_y][sz[pos_x][pos_y]] = point_flag; node[point_flag].val += val[pos_x][pos_y]; node2[point_flag].val += val[pos_x][pos_y]; } } } } sort(node + 1, node + n*m + 1, cmp); ans = 0; for (i = 1; i <= n; i++) { for (j = 1; j <= m; j++) { res.clear(); for (h = 1; h <= k; h++) { if (i + dx[h] >= 1 && i + dx[h] <= n&&j + dy[h] >= 1 && j + dy[h] <= m) { int pos_x = i + dx[h]; int pos_y = j + dy[h]; int s = sz[pos_x][pos_y]; for (g = 1; g <= s; g++) { int x = con[pos_x][pos_y][g] / m + 1; int y = con[pos_x][pos_y][g] % m; if (x == i&&y == j)continue; else { int p1_flag = (i - 1)*m + j; int p2_flag = (x - 1)*m + y; if (flag_cal[p2_flag])continue; int s1 = min(p1_flag, p2_flag); int s2 = max(p1_flag, p2_flag); res[make_pair(s1, s2)] -= val[pos_x][pos_y]; } } } } for (h = 1; h <= k*k + 1; h++) { int x = node[h].id / m + 1; int y = node[h].id%m; int p1_flag = (i - 1)*m + j; int p2_flag = (x - 1)*m + y; if (flag_cal[p2_flag])continue; int s1 = min(p1_flag, p2_flag); int s2 = max(p1_flag, p2_flag); if (s1 == s2)continue; ans = max(ans, res[make_pair(s1, s2)] + node2[p1_flag].val + node[h].val); if (res[make_pair(s1, s2)] == 0) break; } flag_cal[(i - 1)*m + j] = 1; } } printf("%d\n", ans); } int main() { //freopen("i.txt", "r", stdin); //freopen("o.txt", "w", stdout); int t; scanf("%d", &t); while (t--) { input(); solve(); } return 0; }
相关文章推荐
- xampp php环境搭建注意事项
- 基于Struts2的验证码程序
- jenkins中subversion由于服务器时间不一致导致无法更新到最新svn的解决方法
- POJ 1860 Currency Exchange(bellman变形)
- Java对象的强、软、弱和虚引用原理+结合ReferenceQueue对象构造Java对象的高速缓存器
- ubuntu利用live-cd修复grub
- WindowManager service
- 9.在Tachyon上运行Spark
- csproj OutputType
- LeetCode 2016.2.18 290,299,13
- win7上使用vb鼠标滚动
- PHP之mongodb学习
- php 中ASCII编码的使用
- ASP.NET 路由
- HDU1659-GCD-容斥原理
- SQLServer存储过程参数值为空时不作为查询条件
- 点击<a>标签,禁止页面自动跳到顶部的解决办法
- [算法学习]树的广度遍历
- 8.在Tachyon运行MapReduce
- ionic apk文件重签名