“玲珑杯”第七届郑州轻工业学院ACM程序设计大赛——正式赛
G 矩阵:
http://acm.zzuli.edu.cn/problem.php?id=1731
其实一开始我是没读懂题的。一直到前天同学给讲了讲。这两天又看了看学长的题解:http://www.cnblogs.com/chenchengxun/p/4443528.html
现在发现这题也不算什么啊(heiheihei,借鉴借鉴别人处理的小技巧还是极好的
#include<stdio.h>
#include<iostream>
using namespace std;
#define maxn 1000
int dp[maxn+10][maxn+10];
int k;// 全局变量 k 指改变的次数 。即 M 函数执行次数
struct p
{
int x, y, v;
}P[maxn+10];//用以存储M函数所做的工作,x,y代表被改变的数的坐标,v代表被改变后的值。数组存储意味改变不只一次
void Q();// Q函数就是Q之后要做的工作,写成函数的形式的好处就不说了
void M();// M函数意思同Q函数
int main()
{
int n, m, t, w, i, j;
char str[5];
for(i = 1; i <= maxn; i++)
{
for(j = 1; j <= maxn; j++)
dp[i][j] = i + j + dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1];// 先打表。每个坐标的dp 的值 指从 点(1, 1) 到 这个坐标 所有经过的点 的和。i+j指这个坐标原应的值
}
scanf("%d", &t);
while(t--)
{
scanf("%d%d%d", &n, &m, &w);// 很明显n,m没有用。想起来小学时的数学应用题。是,迷惑你的
k = 0;// 别忘了初始化
while(w--)
{
scanf("%s", str);
if(str[0] == 'Q') // 判断之后是执行 Q 函数还是M 函数
Q();
else if(str[0] == 'M')
M();
}
}
return 0;
}
void M()
{
int i;
cin >> P[k].x >> P[k].y >> P[k].v; // 读入3个数,x,y代表坐标。v代表被改变之后的数
for(i = 0; i < k; i++)
{
if(P[i].x == P[k].x && P[i].y == P[k].y) // 相同坐标可能 被改变多次
{
P[i].v = P[k].v;
break;
}
}
k++;
}
void Q()
{
p a, b;
int ans, i;
cin >> a.x >> a.y >> b.x >> b.y;
ans = dp[b.x][b.y] + dp[a.x-1][a.y-1] - dp[a.x-1][b.y] - dp[b.x][a.y-1]; // 分块累计计算。好像初中做的求相框之类的问题。就是多加了一块区域再减去。一画图就知道了
for(i = 0; i < k; i++)
{
if(P[i].x >= a.x && P[i].x <= b.x && P[i].y >= a.y && P[i].y <= b.y) // 判断 M 函数是否对要计算的结果有影响
ans = ans - P[i].x - P[i].y + P[i].v; // 加加减减。。得结果。你怎么看?
}
printf("%d
", ans); // 输出结果果果果果
}
嗯,就这样