这题其实比较水,由于相关算法还不太会,硬生生的给水过了,但有一个WA点让我们找了好久。。。。
这题大致意思就是有一个矩阵A每一个元素的值都是行标列标之和(Aij= i+j )
然后又两种操作:
M x y u 就是把Axy的值改变为u
Q x y u v 就是求(x,y)与(u,v)为对角线位置的子矩阵的值的和
操作做多有1000个,M操作做多10个
矩阵的行与列 <= 1000
详解看AC代码:
#include
#include
#include
#include
#include
using namespace std;
typedef struct _1
{
int x;
int y;
}Point;
Point point[20]; //记录改变的点
int key[20]; //记录改变的值
//其实就是不会用map来模仿一下 =。=
int main()
{
int Case,n,m,q,res,id,count,val,repeat;
int i,j,k,w;
int x,y,v,u;
char flag;
for(i = 0 ; i < 20 ; i++)
{
key[i] = 0;
point[i].x = 0;
point[i].y = 0;
}
id = 1;
scanf("%d",&Case);
while(Case--)
{
count = 0;
printf("Case #%d:\n",id++);
scanf("%d%d%d",&n,&m,&q);
for(k = 0 ; k < q ;k++)
{
getchar();
scanf("%c",&flag);
if(flag == 'Q')
{
scanf("%d%d%d%d",&x,&y,&u,&v);
res = (((x+y)+(x+v))*(v-y+1)/2)*(u-x+1) + (v-y+1)*(u-x+1)*(u-x)/2;
//这个矩阵的数值是有规律的,只需要算出三个顶点的坐标就可以求出原子矩阵的和
for(w = 0 ; w <= count ; w++)
if(x <= point[w].x && point[w].x <= u && y <= point[w].y && point[w].y <= v)
res += key[w];
//这里有个WA点,如果被改变的点在n,m范围内而不在(x,y) ,(u,v)子矩阵范围内不可以加上它
printf("%d\n",res);
}
else
{
scanf("%d%d%d",&x,&y,&u);
val = u-x-y;
repeat = 0;
for(w = 0 ; w <= count ; w++) //M操作最多只有10次所以可以历遍
if(x == point[w].x && y == point[w].y)
{
repeat = 1;
break;
}
if(repeat) //取改点最新的改变值
key[w] = val;
else
{
point[count].x = x;
point[count].y = y;
key[count++] = val;
}
}
}
for(k = 0 ; k < 20 ; k++)
{
point[k].x = 0;
point[k].y = 0;
key[k] = 0;
}
}
return 0;
}