题目分析:
- 我们可以得到一些性质:每个点只能被操作一次,若操作一次以上,显然不是最小值
- 当我们前一行定下来,就不受后面的影响
- 我们可以枚举第一行的状态,操作哪些点,这样可以覆盖问题的所有状态
- 将枚举的状态操作,接下来递推
- 从第1行推到第4行,当第
i
i
i行的
j
j
j为
0
0
0,就操作
(
i
+
1
,
j
)
(i+1,j)
(i+1,j),这样就可以定下
i
i
i行的状态去推
i
+
1
i+1
i+1行,并且第
i
i
i行不受第
i
+
1
i+1
i+1行影响
- 最后判断第
n
n
n行是否合法即可
A:Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 1000000007
int T;
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
char s[10][10],g[10][10];
inline void init_() {
freopen("a.txt","r",stdin);
}
inline int read_() {
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=(x<<1)+(x<<3)+c-'0';
c=getchar();
}
return x*f;
}
inline void turn_(int x,int y) {
if(x<0||y<0||x>4||y>4) return;
g[x][y]^=1;
for(int i=0;i<4;++i) {
int px=x+dx[i];
int py=y+dy[i];
if(px>=0&&py>=0&&px<5&&py<5) {
g[px][py]^=1;
}
}
}
inline int work_() {
int ans=INF,cnt,pd;
for(int i=0;i<(1<<5);++i) {
memcpy(g,s,sizeof(g));
cnt=0;pd=0;
for(int j=0;j<5;++j) {
if( (i>>j) & 1 ) {
++cnt;
if(cnt>6) {
pd=1;
break;
}
turn_(0,j);
}
}
if(pd) continue;
for(int j=0;j<4;++j) {
for(int k=0;k<5;++k) {
if(g[j][k]=='0') {
++cnt;
if(cnt>6) {
pd=1;
break;
}
turn_(j+1,k);
}
}
}
if(pd) continue;
pd=1;
for(int j=0;j<5;++j) {
if(g[4][j]=='0') {
pd=0;
break;
}
}
if(pd) ans=min(ans,cnt);
else continue;
}
if(ans==INF) return -1;
else return ans;
}
void readda_() {
T=read_();
while(T--) {
for(int i=0;i<5;++i) {
scanf("%s",s[i]);
}
printf("%d\n",work_());
}
}
int main() {
init_();
readda_();
return 0;
}
B:Code
#include <bits/stdc++.h>
using namespace std;
#define INF 1000000007
int dx[]={0,1,-1,0,0};
int dy[]={0,0,0,1,-1};
int b[10][10],a[10][10];
char s[10];
inline void init_() {
freopen("a.txt","r",stdin);
}
inline int read_() {
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=(x<<1)+(x<<3)+c-'0';
c=getchar();
}
return x*f;
}
inline void turn_(int x,int y) {
if(x<1||y<1||x>4||y>4) return;
a[x][y]^=1;
for(int i=1;i<=4;++i) {
int px=x+dx[i];
int py=y+dy[i];
if(px>=1&&py>=1&&px<=4&&py<=4) {
a[px][py]^=1;
}
}
}
inline int work_(int pdc) {
int ans=INF,cnt,pd;
for(int i=0;i<(1<<4);++i) {
memcpy(a,b,sizeof(a));
cnt=0;pd=0;
for(int j=0;j<4;++j) {
if( (i>>j) & 1 ) {
++cnt;
if(cnt>16) {
pd=1;
break;
}
turn_(1,j+1);
}
}
if(pd) continue;
for(int j=1;j<=3;++j) {
for(int k=1;k<=4;++k) {
if(a[j][k]!=pdc) {
++cnt;
if(cnt>16) {
pd=1;
break;
}
turn_(j+1,k);
}
}
if(pd) break;
}
if(pd) continue;
pd=1;
for(int j=1;j<=4;++j) {
if(a[4][j]!=pdc) {
pd=0;
break;
}
}
if(pd) ans=min(ans,cnt);
}
return ans;
}
void readda_() {
for(int i=1;i<=4;++i) {
scanf("%s",s);
for(int j=0;j<4;++j) {
if(s[j]=='w') b[i][j+1]=0;
else b[i][j+1]=1;
}
}
int AKIOI=work_(0);
AKIOI=min(AKIOI,work_(1));
if(AKIOI==INF) printf("Impossible\n");
else printf("%d",AKIOI);
}
int main() {
init_();
readda_();
return 0;
}
C:Code
#include <bits/stdc++.h>
using namespace std;
#define INF 1000000007
#define maxn 20
int maxd,n,b[maxn][maxn],a[maxn][maxn];
int dx[]={0,1,-1,0,0};
int dy[]={0,0,0,1,-1};
char s[maxn];
inline void init_() {
freopen("a.txt","r",stdin);
}
inline int read_() {
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=(x<<1)+(x<<3)+c-'0';
c=getchar();
}
return x*f;
}
inline void turn_(int x,int y) {
if(x<1||y<1||x>n||y>n) return;
a[x][y]^=1;
for(int i=1;i<=4;++i) {
int px=x+dx[i];
int py=y+dy[i];
if(px<1||py<1||px>n||py>n) continue;
a[px][py]^=1;
}
}
inline int work_(int pdc) {
int ans=INF,cnt,pd;
for(int i=0;i<(1<<n);++i) {
memcpy(a,b,sizeof(a));
cnt=0;pd=0;
for(int j=0;j<n;++j) {
if( (i>>j) & 1 ) {
++cnt;
if(cnt>maxd) {
pd=1;
break;
}
turn_(1,j+1);
}
}
if(pd) continue;
for(int j=1;j<n;++j) {
for(int k=1;k<=n;++k) {
if(a[j][k]!=pdc) {
++cnt;
if(cnt>maxd) {
pd=1;
break;
}
turn_(j+1,k);
}
}
if(pd) break;
}
if(pd) continue;
pd=1;
for(int j=1;j<=n;++j) {
if(a[n][j]!=pdc) {
pd=0;
break;
}
}
if(pd) ans=min(ans,cnt);
}
return ans;
}
void readda_() {
n=read_();
for(int i=1;i<=n;++i) {
scanf("%s",s);
for(int j=0;j<n;++j) {
if(s[j]=='b') b[i][j+1]=1;
else b[i][j+1]=0;
}
}
maxd=n*n;
int AKIOI=min(work_(0),work_(1));
if(AKIOI==INF) printf("Impossible");
else printf("%d",AKIOI);
}
int main() {
init_();
readda_();
return 0;
}