ACM-ICPC 2018南京赛区网络预赛 B. The writing on the wall
Problem Description
Feeling hungry, a cute hamster decides to order some take-away food (like fried chicken for only 30 Yuan).
However, his owner CXY thinks that take-away food is unhealthy and expensive. So she demands her hamster to fulfill a mission before ordering the take-away food. Then she brings the hamster to a wall.
The wall is covered by square ceramic tiles, which can be regarded as a n∗m grid. CXY wants her hamster to calculate the number of rectangles composed of these tiles.
For example, the following 3∗3 wall contains 36 rectangles:
Such problem is quite easy for little hamster to solve, and he quickly manages to get the answer.
Seeing this, the evil girl CXY picks up a brush and paint some tiles into black, claiming that only those rectangles which don’t contain any black tiles are valid and the poor hamster should only calculate the number of the valid rectangles. Now the hamster feels the problem is too difficult for him to solve, so he decides to turn to your help. Please help this little hamster solve the problem so that he can enjoy his favorite fried chicken.
Input
There are multiple test cases in the input data.
The first line contains a integer T : number of test cases. T≤5.
For each test case, the first line contains 3 integers n,m,k , denoting that the wall is a n×m grid, and the number of the black tiles is k.
For the next k lines, each line contains 2 integers: x y ,denoting a black tile is on the x-th row and y-th column. It’s guaranteed that all the positions of the black tiles are distinct.
For all the test cases,
1≤n≤1e5, 1≤m≤100, 0≤k≤1e5 , 1≤x≤n,1≤y≤m.
It’s guaranteed that at most 2 test cases satisfy that n≥20000.
Output
For each test case, print “Case #x: ans” (without quotes) in a single line, where x is the test case number and ans is the answer for this test case.
Hint
The second test case looks as follows:
样例输入
2
3 3 0
3 3 1
2 2
样例输出
Case #1: 36
Case #2: 20
题目来源
ACM-ICPC 2018 南京赛区网络预赛
题意
给一个N*M大小的矩形,其中有K个单位小正方形不可访问。
问,N*M的矩形有多少个子矩形(都不包含那K个小正方形)
思路
N比较大,而M比较小,所以如果想循环的话无非选择NorM作为外层循环,在确定循环层数后,选择时间复杂度小的顺序循环即可
首先简化问题,如果K=0,即N*M的矩形的所有子矩形都要参与计算。
这时可以外层循环为N,即每次计算固定高度的子矩形
容易知道对于固定高度矩形的答案数为 1+2+3+。。。+M,即 M *(1+M) / 2
这部分可以用一个公式就直接得出答案,但是题目里有K个点不能出现在子矩阵里
所以可以先写一个三重的循环,看看如何改
for(h=1;h<=n;h++){
for(i=1;i<=m;i++){
for(j=i;j>=1;j--){
ans+=h;
}
}
}
可以知道如果对于高度为H的矩形里有一个不能访问的点,就不能ans+h
所以要根据输入,处理出高度为H的矩形被不可访问点拦断的高度h。。。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define maxn 100010
#define maxm 110
bool p[maxn][maxm];
int up[maxn];
int main()
{
int t,Case=0;;
scanf("%d",&t);
while(t--){
memset(p,0,sizeof(p));
memset(up,0,sizeof(up));
int i,j,h,n,m,num;
int x,y;
scanf("%d %d %d",&n,&m,&num);
for(i=1;i<=num;i++){
scanf("%d %d",&x, &y);
p[x][y]=1;
}
ll ans=0;
ll k;
for(h=1;h<=n;h++){
for(i=1;i<=m;i++){
if(p[h][i]){
up[i]=h;
}
}
for(i=1;i<=m;i++){
k=inf;
for(j=i;j>=1;j--){
k=min(k,(ll)(h-up[j]));
ans+=k;
}
}
}
printf("Case #%d: %lld\n",++Case,ans);
}
return 0;
}