题解 CF1359B 【New Theatre Square】

题意

有一个 n×m 的广场,其中一部分要铺地砖,地砖有两种, 1 × 1 和 1×2 的,后者只能横着铺,其中, 1 × 1的单价为 x , 1 × 2 的单价为 y , 输入这个广场,"."表示要铺地砖,求最少花费。注意,地砖不可重合,也不可覆盖在已铺地砖区域。

思路

这显然是贪心,分别计算全铺 $ 1 × 1$ 的方案价钱和尽量多铺 $ 1 × 2$ 的方案价钱,最后将最小的输出,因为只能横铺,方向固定,所以十分简单。

代码

具体细节见注释

#include
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
#define floor Fl //好像floor是关键字?于是我宏定义了一下
#define lol long long
#define re read()
using namespace std;
const int MAXN=1e3+10;
int read(){
	#define ge getchar()
	int x=0,sgn=1;char ch=ge;
	for(;!isdigit(ch);ch=ge)if(ch=='-')sgn=-1;
	for(;isdigit(ch);ch=ge)x=(x<<1)+(x<<3)+(ch^48);
	return x*sgn;
}
int T,n,m,x,y;
int floor[MAXN][MAXN];
int main (){
	T=re;
	while(T--){
		n=re;m=re;x=re;y=re;int tot1=0,tot2=0;
		_rep(i,1,n){
			_rep(j,1,m){
				char ch=ge;
				while(ch!='.'&&ch!='*')ch=ge;
				if(ch=='.'){
					floor[i][j]=1;
					tot1++;
                    //tot1表示除了被铺1*2的,可铺多少1*1的地砖
					if(floor[i][j-1]&&floor[i][j])floor[i][j-1]=0,floor[i][j]=0,tot1-=2,tot2++;
                    //tot2表示可以最多铺多少1*2 的地砖
				}
				else floor[i][j]=0;
			}
		}
		lol ans1=tot1*x+tot2*y,ans2=tot1*x+tot2*2*x;
		//计算方案,lol:long long
        printf("%lld\n",min(ans1,ans2));
	}
	return 0;
}

你可能感兴趣的:(题解 CF1359B 【New Theatre Square】)