标签:第一行 CH0201 int res 费解 ++ 开关 ans const
思路
本题可以直接用bfs去做,时间复杂度较高,本文来说说递推的做法。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 5;
const int INF = 10000000;
const int dx[5] = {0,1,0,-1,0};
const int dy[5] = {0,0,1,0,-1};
int t;
char g[N][N];
void turn(int x,int y)
{
for(int i = 0;i < 5;i ++ )
{
int a = x + dx[i];
int b = y + dy[i];
if(a < 5 && a >= 0 && b < 5 && b >= 0)
{
g[a][b] ^= 1;
}
}
}
int work()
{
int ans = INF;
for(int i = 0;i < 1 << 5;i ++ )
{
int res = 0;
char backup[N][N];
memcpy(backup,g,sizeof g);
for(int j = 0;j < 5;j ++ )
{
if(i >> j & 1)
{
res ++ ;
turn(0,j);
}
}
for(int i = 0;i < 4;i ++ )
{
for(int j = 0;j < 5;j ++ )
{
if(g[i][j] == '0')
{
res ++ ;
turn(i + 1,j);
}
}
}
int flag = true;
for(int i = 0;i < 5;i ++ )
{
if(g[4][i] == '0')
{
flag = false;
break;
}
}
if(flag) ans = min(ans,res);
memcpy(g,backup,sizeof g);
}
if(ans > 6) ans = -1;
return ans;
}
int main()
{
cin >> t;
while(t -- )
{
for(int i = 0;i < 5;i ++ ) cin >> g[i];
cout << work() << endl;
}
return 0;
}
三个性质:
- 每个位置至多会被点击一次。
- 若固定了第一行,则满足题意的点击方案至多只有一种。其原因是:当第\(i\)行某一位为\(1\)时,若前\(i\)行已被固定,则只能点击\(i + 1\)行使第\(i\)行改变。
- 点击的先后顺序不影响结果。
我们去枚举第一行的所有可能情况,并不改变第一行,只按第二行的开关。由性质\(2\)可得,若到达第\(n\)行不全为\(0\),说明第一行的这种枚举情况是错误的。若到达第\(n\)行全为\(0\),则说明第一行的枚举情况是正确的,更新一下答案即可。
标签:第一行,CH0201,int,res,费解,++,开关,ans,const 来源: https://www.cnblogs.com/breadcomplex/p/15102353.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。