2022.3.16
蓝书
AcWing 181. 回转游戏
思路:一开始先得把表给打好,就是每个数字对应的位置找到,到时候换位置的时候就很方便不用一个个打。我们的目的是把中间八个格子变成一样的,对于中间八个里的某一个数,变成一样的次数为8-该数的个数。把它当成估计函数,如果当前的操作次数加上估计函数已经超过了限定的次数就退出。当需要的次数为0的时候说明已经成功了。还需要剪枝,当当前操作是上一个操作的反操作的时候就剪,因为这样做等于又恢复原状了,等于没变。
打表看了代码,其他没看自己写。vector和char数组比很慢。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=30+10,INF=1e8;
int db[10][10] =
{
{0, 2, 6, 11, 15, 20, 22},
{1, 3, 8, 12, 17, 21, 23},
{10, 9, 8, 7, 6, 5, 4},
{19, 18, 17, 16, 15, 14, 13},
{23, 21, 17, 12, 8, 3, 1},
{22, 20, 15, 11, 6, 2, 0},
{13, 14, 15, 16, 17, 18, 19},
{4, 5, 6, 7, 8, 9, 10},
};
int fop[10] = {5, 4, 7, 6, 1, 0, 3, 2};
int cen[10] = {6, 7, 8, 11, 12, 15, 16, 17};
int a[N];
vector<char> ans;
int check()
{
int ans = 0;
int sum[5] = {0};
for (int i = 0; i < 8;i++)
{
sum[a[cen[i]]]++;
}
for (int i = 1;i<=3;i++)
{
ans = max(ans, sum[i]);
}
return 8 - ans;
}
void change(int op)
{
int x = a[db[op][0]];
for (int i = 0; i < 6;i++)
a[db[op][i]] = a[db[op][i + 1]];
a[db[op][6]] = x;
}
bool dfs(int dep,int tot,int last)
{
if(check()+tot>dep)
return 0;
if(check()==0)
return 1;
for (int i = 0; i < 8;i++)
{
if(i==last)
continue;
change(i);
ans.push_back('A' + i);
if(dfs(dep,tot+1,fop[i]))
return 1;
ans.pop_back();
change(fop[i]);
}
return 0;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
while(cin>>n)
{
if(n==0)
break;
a[0] = n;
for (int i = 1; i < 24;i++)
{
cin >> a[i];
}
int dep = 0;
while(!dfs(dep,check(),-1))
dep++;
if(dep)
{
for(auto x:ans)
cout << x;
cout <<'\n'<<a[8]<<'\n';
}
else
cout << "No moves needed"<<'\n'<<a[8]<<'\n';
while(ans.size())
ans.pop_back();
}
return 0;
}
AcWing 188. 武士风度的牛
时间有点晚,挑了道简单的bfs模板题练手
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=150+10,INF=1e8;
char mp[N][N];
int r, c,ans,vis[N][N],dis[N][N];
int dx[8] = {1, 2, 2, 1, -1, -2, -2, -1}, dy[8] = {2, 1, -1, -2, -2, -1, 1, 2};
queue<pii> que;
bool check(int x,int y)
{
return x >= 1 && x <= r && y >= 1 && y <= c && mp[x][y] != '*';
}
void bfs()
{
while(que.size())
{
auto t = que.front();
que.pop();
int x = t.first, y = t.second;
if(vis[x][y])
continue;
vis[x][y] = 1;
for (int i = 0; i < 8;i++)
{
int xx = x + dx[i], yy = y + dy[i];
if(check(xx,yy)&&dis[xx][yy]==INF)
{
dis[xx][yy] = dis[x][y] + 1;
if (mp[xx][yy] == 'H')
return;
que.push({xx, yy});
}
}
}
return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> c >> r;
for (int i = 1; i <= r;i++)
for (int j = 1; j <= c;j++)
dis[i][j] = INF;
int xx, yy;
for (int i = 1; i <= r;i++)
{
for (int j = 1; j <= c;j++)
{
cin >> mp[i][j];
if(mp[i][j]=='K')
{
que.push({i, j});
dis[i][j] = 0;
}
if (mp[i][j] == 'H')
{
xx = i, yy = j;
}
}
}
bfs();
cout << dis[xx][yy];
return 0;
}
AcWing 189. 乳草的入侵
bfs模板
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=100+10,INF=1e8;
char mp[N][N];
int n, m,y,x,vis[N][N],dis[N][N],ans;
int dx[8] = {-1, 0, 1, -1, 1, -1, 0, 1}, dy[8] = {1, 1, 1, 0, 0, -1, -1, -1};
queue<pii> que;
bool check(int x,int y)
{
return x >= 1 && x <= n && y >= 1 && y <= m&&mp[x][y]!='*';
}
bool check1()
{
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= m;j++)
{
if(mp[i][j]=='.')
return 0;
}
}
return 1;
}
void bfs()
{
while(que.size())
{
auto t = que.front();
que.pop();
int x = t.first, y = t.second;
for (int i = 0; i < 8;i++)
{
int xx = x + dx[i], yy = y + dy[i];
if(check(xx,yy)&&!vis[xx][yy])
{
vis[xx][yy] = 1;
dis[xx][yy] = dis[x][y] + 1;
mp[x][y] = 'M';
ans = max(ans, dis[xx][yy]);
if(check1())
return;
que.push({xx, yy});
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> m >> n >>y>>x;
for (int i = n; i >= 1;i--)
{
for (int j = 1; j <= m;j++)
{
cin >> mp[i][j];
dis[i][j] = INF;
}
}
mp[x][y] = 'M';
dis[x][y] = 0;
que.push({x, y});
bfs();
cout << ans;
return 0;
}