题解 CF1359B 【New Theatre Square】
题意
有一个 n×m 的广场,其中一部分要铺地砖,地砖有两种, 1 × 1 和 1×2 的,后者只能横着铺,其中, 1 × 1的单价为 x , 1 × 2 的单价为 y , 输入这个广场,"."表示要铺地砖,求最少花费。注意,地砖不可重合,也不可覆盖在已铺地砖区域。
思路
这显然是贪心,分别计算全铺 $ 1 × 1$ 的方案价钱和尽量多铺 $ 1 × 2$ 的方案价钱,最后将最小的输出,因为只能横铺,方向固定,所以十分简单。
代码
具体细节见注释
#include<bits/stdc++.h>
#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;
}
本博客作者:Werner_Yin(https://www.cnblogs.com/werner-yin/) ,转载时请注明出处,谢谢支持!