题目大意:一共R排,每排S个座椅,一共有B个座椅是坏的,坐的时候要求相邻两个位置只能坐一个人,求最多和最少坐多少人后不能再坐人
题目分析:预处理坏的位置,为了方便计算,在最左和最右再加两列坏的座位,然后只要枚举任意两对坏座位之间的情况即可,最大时偶数除/2,奇数/2+1,最小时每三个位子坐一个人能占据的空间最大
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 1005;
int r, s, b;
int a[MAX][MAX];
struct B
{
int x, y;
}bk[MAX * 10];
bool cmp(B a, B b)
{
if(a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
int get_ma(int x)
{
if(x == 0)
return 0;
if(x < 3)
return 1;
if(x & 1)
return (x + 1) / 2;
return x / 2;
}
int get_mi(int x)
{
if(x == 0)
return 0;
if(x < 3)
return 1;
return x / 3 + (x % 3 != 0);
}
int main()
{
int T;
scanf("%d", &T);
for(int ca = 1; ca <= T; ca++)
{
int cnt = 0;
scanf("%d %d %d", &r, &s, &b);
for(int i = 0; i < b; i++)
{
scanf("%d %d", &bk[cnt].x, &bk[cnt].y);
bk[cnt].x ++;
bk[cnt].y ++;
cnt ++;
}
for(int i = 1; i <= r; i++)
{
bk[cnt].x = i;
bk[cnt].y = 0;
cnt ++;
bk[cnt].x = i;
bk[cnt].y = s + 1;
cnt ++;
}
sort(bk, bk + cnt, cmp);
int mi = 0, ma = 0;
for(int i = 0; i < cnt - 1; i++)
{
if(bk[i].x == bk[i + 1].x)
{
mi += get_mi(bk[i + 1].y - bk[i].y - 1);
ma += get_ma(bk[i + 1].y - bk[i].y - 1);
}
}
printf("Case #%d: %d %d\n", ca, ma, mi);
}
}