题意:题目意思还是比较清楚的,有一个 n×n 的棋盘,每个格子,每个格子上有个数,其大小为格子的横坐标加上纵坐标。然后给出两种操作,每次操作都要求输出当前行或列存有的数字之和,然后对当前行或列进行清空。
思路:采用记录的方式。因为每个格子的值是 行号+列号,记录下哪些行进行过R操作,哪些列进行过C操作。同时,因为R操作与C操作之间会相互影响行和列的值之和,所以在计算列的值之和时要知道哪几行被清空过,在计算行的值之和时要知道哪几列被清空过。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<utility>
#include<vector>
#include<cmath>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 1000010;
LL n, q;
set<int> Rs;
set<int> Cs;
LL Csum,Rsum;
int main()
{
//freopen("in.txt", "r", stdin);
freopen("adjustment.in", "r", stdin);
freopen("adjustment.out", "w", stdout);
while(scanf("%lld%lld", &n, &q) == 2){
getchar();
Rs.clear();
Cs.clear();
Csum = 0;
Rsum = 0;
char ch;
LL c;
while(q--){
scanf("%c%lld", &ch, &c);
getchar();
if(ch == 'R'){
if(Rs.count(c) == 1){
printf("0\n");
}
else{
printf("%lld\n", n*c+(1+n)*n/2 - Cs.size()*c - Csum);
Rs.insert(c);
Rsum += c;
}
}
else if(ch == 'C'){
if(Cs.count(c) == 1){
printf("0\n");
}
else{
printf("%lld\n", n*c+(1+n)*n/2 - Rs.size()*c - Rsum);
Cs.insert(c);
Csum += c;
}
}
}
}
return 0;
}