2131 - 枚举-练习-涂国旗
c++刷题 超能力编程
分析
枚举涂w的底边和涂b的底边即可
剩下的部分都涂r
数据范围这么小,暴力枚举,代码简单难度低。搜索什么的用不着啦!
那么问题来了:怎么枚举呢?
我们只要枚举白与蓝、蓝与红的边界(如上图a和b),再统计三个区域里总共有多少格子需要涂改颜色,用一个变量来记录最优的答案(即需要涂改的格子数最少),不断更新,最后输出就OK了qwq。
f1:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;const int N = 60;int n, m;
char g[N][N];
int res = 0;int main()
{scanf("%d%d", &n, &m);for(int i = 1; i <= n; i++){for(int j = 1; j <= m; j++){cin >> g[i][j];}} int wst = 1, wend;int res = 3000;int bst, bend, rst, rend;// 枚举涂w的终点行wend 1 -> n-2 for(wend = wst; wend <= n-2; wend++){int tmpa = 0;// wst -> wend 图 w for(int i = wst; i <= wend; i++){for(int j = 1; j <= m; j++){if(g[i][j] != 'W') tmpa++;}}// 枚举涂b的终点行bend wend+1 -> n-1bst = wend + 1, bend;for(bend = bst; bend <= n-1; bend++){int tmpb = 0;for(int i = bst; i <= bend; i++){for(int j = 1; j <= m; j++){if(g[i][j] != 'B') tmpb++;}}// 最后全涂成rfor(int i = bend+1; i <= n; i++){for(int j = 1; j <= m; j++){if(g[i][j] != 'R') tmpb++;}} res = min(res, tmpa + tmpb);}
// res = min(res, tmp);}cout << res << endl;return 0;
}
f2:
int n,m,ans,mi=inf;//mi初始化成一个很大的数
char c[N][N];
int main()
{int i,j,k,g;cin>>n>>m;for(i=1;i<=n;i++)for(j=1;j<=m;j++) cin>>c[i][j];for(i=1;i<=n-2;i++)//由于白色下面还有蓝色和红色,所以i(白与蓝的边界)枚举到(n-2)for(j=i+1;j<=n-1;j++)//j(蓝与红的边界)至少要比i大1,同理枚举到(n-1),这样可以减少枚举次数{ans=0;//初始化//壮观地枚举三个区域for(k=1;k<=i;k++)for(g=1;g<=m;g++) if(c[k][g]!='W') ans++;for(k=i+1;k<=j;k++)for(g=1;g<=m;g++) if(c[k][g]!='B') ans++;for(k=j+1;k<=n;k++)for(g=1;g<=m;g++) if(c[k][g]!='R') ans++;mi=min(ans,mi);//更新答案}cout<<mi<<endl;return 0;
}