https://vjudge.net/article/187
目录
1. poj 1321 棋盘问题
- 一行一行的放,这一行也可以不放,放在下一行再放,放过的列数要标记
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <iomanip>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
int vis[MAXN];
char mp[20][20];
int ans = 0;
int n, k;
void Dfs(int now, int y){
if(now == k){
ans += 1;
return;
}
if(y == n + 1) return;
for(int i=1;i<=n;i++){
if(!vis[i] && mp[y][i] == '#'){
vis[i] = 1;
Dfs(now + 1, y + 1);
vis[i] = 0;
}
}
Dfs(now, y + 1);
}
int main(){
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while(cin >> n >> k){
if(n == -1 && k == -1) break;
ans = 0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin >> mp[i][j];
}
}
Dfs(0, 1);
cout << ans << '\n';
}
return 0;
}
2. poj 2251 Dungeon Master
- 注意输入的顺序,常规 b f s bfs bfs找最短路径
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <iomanip>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
char a[40][40][40];
struct Node{
int x, y, z, ans;
};
int L, R, C;
int xx[] = {0, 0, 0, 0, 1, -1};
int yy[] = {0, 0, -1, 1, 0, 0};
int zz[] = {1, -1, 0, 0, 0, 0};
void bfs(int x1, int y1, int z1){
queue<Node> q;
q.push(Node{x1, y1, z1, 0});
a[x1][y1][z1] = '#';
while(!q.empty()){
Node u = q.front();
q.pop();
if(a[u.x][u.y][u.z] == 'E'){
cout << "Escaped in " << u.ans << " minute(s).\n";
return;
}
for(int i=0;i<6;i++){
int dx = u.x + xx[i];
int dy = u.y + yy[i];
int dz = u.z + zz[i];
if(dx < 1 || dy < 1 || dz < 1 || dx > L || dy > R || dz > C || a[dx][dy][dz] == '#') continue;
if(a[dx][dy][dz] == 'E'){
cout << "Escaped in " << u.ans + 1 << " minute(s).\n";
return;
}
a[dx][dy][dz] = '#';
q.push(Node{dx, dy, dz, u.ans + 1});
}
}
cout << "Trapped!" << '\n';
}
int main(){
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while(cin >> C >> L >> R){
if(L == 0 && R == 0 && C == 0) break;
int x1, y1, z1, x2, y2, z2;
x1 = y1 = z1 = x2 = y2 = z2 = -1;
for(int k=1;k<=C;k++){
for(int i=1;i<=L;i++){
for(int j=1;j<=R;j++){
cin >> a[i][j][k];
if(a[i][j][k] == 'S'){
x1 = i;
y1 = j;
z1 = k;
}
}
}
}
bfs(x1, y1, z1);
}
return 0;
}
3. poj 3278 Catch That Cow
- **题,注意标记已经走过的状态,数组别越界
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 1e6 + 100;
int vis[MAXN];
struct st{
int val;
int ans;
};
int bfs(){
int n, k;
cin >> n >> k;
if(k <= n){
return n - k;
}
queue<st> q;
st x;
x.ans = 0;
x.val = n;
q.push(x);
while(!q.empty()){
st u = q.front();
q.pop();
int a = u.val - 1;
int b = u.val + 1;
int c = u.val * 2;
if(a == k || b == k || c == k){
return u.ans + 1;
}
if(b >= 0 && !vis[b]){
vis[b] = 1;
x.val = b;
x.ans = u.ans + 1;
q.push(x);
}
if(c < MAXN && c >= 0 && !vis[c]){
vis[c] = 1;
x.val = c;
x.ans = u.ans + 1;
q.push(x);
}
if(a >= 0 && !vis[a]){
vis[a] = 1;
x.val = a;
x.ans = u.ans + 1;
q.push(x);
}
}
return -1;
}
int main(){
cout << bfs();
return 0;
}
4. poj 3279 Fliptile
- 这道题只要想到了先确定第一行,那就不难了,第一行我们用二进制枚举每一个状态,很常规的操作,这样确保最后按照字典序输出,因为每次的枚举,第一行能够唯一确定,所以最后的答案也是唯一确定的
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <iomanip>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
int a[MAXN];
int mp[20][20];
int mp2[20][20];
int ans[20][20];
void change(int x, int y){
mp2[x - 1][y] ^= 1;
mp2[x + 1][y] ^= 1;
mp2[x][y] ^= 1;
mp2[x][y + 1] ^= 1;
mp2[x][y - 1] ^= 1;
}
void print(int m, int n){
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
cout << ans[i][j] << ' ';
}cout << '\n';
}
}
void solve(int m, int n){
for(int k=0;k<(1<<n);k++){
memcpy(mp2, mp, sizeof mp);
memset(ans, 0, sizeof ans);
for(int j=1;j<=n;j++){
if(k & (1 << (j - 1))){
change(1, j);
ans[1][j] = 1;
}
}
for(int i=2;i<=m;i++){
for(int j=1;j<=n;j++){
if(mp2[i - 1][j]){
change(i, j);
ans[i][j] = 1;
}
}
}
for(int j=1;j<=n;j++){
if(mp2[m][j]) break;
if(j == n){
print(m, n);
return;
}
}
}
cout << "IMPOSSIBLE";
}
int main(){
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int m, n;
cin >> m >> n;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
cin >> mp[i][j];
}
}
solve(m, n);
return 0;
}
5. poj 1426 Find The Multiple
- 暴力,可以先打出来200个看一看对不对,都是由1和0组成的就对了
- 要是T了就换G++编译器
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#include <iomanip>
#include <climits>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 100;
const double eps = 1e-6;
int a[MAXN];
ll bfs(ll n){
queue<ll> q;
q.push(1);
while(!q.empty()){
ll u = q.front();
q.pop();
if(u % n == 0) return u;
q.push(u * 10);
q.push(u * 10 + 1);
}
return -1;
}
int main(){
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll n;
vector<ll> ans(201);
for(ll i=1;i<=200;i++){
ans[i] = bfs(i);
}
while(cin >> n && n){
cout << ans[n] << '\n';
}
return 0;
}
6. poj 3126 Prime Path
发现两年前做过了,应该很简单吧,下面是当时写的
#include <iostream>
#include <queue>
#include <cstring>
#define maxn 5
int step[10000+maxn],vis[10000+maxn];
int prime[10000+maxn];
using namespace std;
bool Is_prime(int n){
if(n==2) return true;
if(n==1||n%2==0) return false;
for(int i=3;i<n;i+=2){
if(n%i==0) return false;
}
return true;
}
void init(){
for(int i=1000;i<10000;i++){
if(Is_prime(i)) prime[i]=1;
}
}
int BFS(int dx,int dy){
queue<int> q;
int a[10];
q.push(dx);
memset(step,0,sizeof(step));
memset(vis,0,sizeof(vis));
vis[dx]=1;
while(!q.empty()){
int x=q.front();
q.pop();
if(x==dy) return step[dy];
a[0]=x%10;a[1]=x%100/10;a[2]=x%1000/100;a[3]=x/1000;
for(int i=0;i<4;i++){
int num=a[i];
for(int iu=0;iu<10;iu++){
if(iu!=num){
a[i]=iu;
int temp=a[0]+10*a[1]+100*a[2]+1000*a[3];
if(prime[temp]&&!vis[temp]){
step[temp]=step[x]+1;
vis[temp]=1;
q.push(temp);
}
}
}
a[i]=num;
}
}
return -1;
}
int main(){
init();
int T;
int dx,dy;
cin>>T;
while(T--){
cin>>dx>>dy;
int ret=BFS(dx,dy);
if(ret==-1) cout<<"Impossible";
else cout<<ret<<endl;
}
//system("pause");
return 0;
}
7. poj 3087 Shuffle’m Up
- 三行字符串,表示从底到顶的颜色,第一行是 S 1 S_1 S1,第二行是 S 2 S_2 S2,第三行是目标,每次按照图示洗牌完毕截取下面的 C C C个作为新的 S 1 S_1 S1,上面作为新的 S 2 S_2 S2,重复操作下去,问多少次操作能达到目标或者永远也达不到
- 题读懂了以后直接模拟即可,如何判-1?目测次数不会很多,直接暴力跑一千次,出不来就是-1;或者标记是否这个状态出现过,如果出现过那也能说明达不到,肯定是这个方法比较快
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#include <iomanip>
#include <climits>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 100;
const double eps = 1e-6;
int a[MAXN];
int main(){
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
string s1, s2, s;
cin >> n;
for(int i=1;i<=n;i++){
cin >> m;
cin >> s1 >> s2 >> s;
reverse(s1.begin(), s1.end());
reverse(s2.begin(), s2.end());
reverse(s.begin(), s.end());
bool flag = false;
int ans = 0;
map<string, int> mp;
while(true){
string ss = "";
for(int k=0;k<m;k++){
ss += s1[k];
ss += s2[k];
}
// cout << j << '\n';
// cout << s1 << ' ' << s2 << '\n';
// cout << ss << ' ' << s << '\n';
ans += 1;
if(ss == s){
flag = true;
break;
}
if(mp.count(ss)) break;
mp[ss] = 1;
if(m != 1){
s1 = ss.substr(m);
s2 = ss.substr(0, m);
}else{
swap(s1, s2);
}
}
if(flag) cout << i << ' ' << ans << '\n';
else cout << i << ' ' << -1 << '\n';
}
return 0;
}
8. FZU 2150 Fire Game
- 题意是这样的,选择两个草坪开始烧,草坪可以选择同一个,且只能往周围四个位置传递影响,问最少需要多长时间把所有草坪烧完
- 双起点 b f s bfs bfs,然后暴力
- 这个题我提交不了,但是跟别人代码对拍感觉没什么问题,扫一眼看起来思路是一样的
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <iomanip>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
char mp[12][12];
int vis[12][12];
int n, m;
struct Node{
int x, y;
int tim;
}s[200];
int tot;
int ans;
int now;
int xx[] = {-1, 1, 0, 0};
int yy[] = {0, 0, -1, 1};
void bfs(int x1, int y1, int x2, int y2){
Node x;
x.x = x1;
x.y = y1;
x.tim = 0;
queue<Node> q;
q.push(x);
vis[x1][y1] = 1;
x.x = x2;
x.y = y2;
x.tim = 0;
if(!vis[x2][y2]) q.push(x);
vis[x2][y2] = 1;
now = 0;
while(!q.empty()){
x = q.front();
q.pop();
for(int i=0;i<4;i++){
int dx = x.x + xx[i];
int dy = x.y + yy[i];
if(dx < 1 || dy < 1 || dx > n || dy > m || mp[dx][dy] == '.' || vis[dx][dy] == 1) continue;
vis[dx][dy] = 1;
Node u;
u.tim = x.tim + 1;
u.x = dx;
u.y = dy;
q.push(u);
now = max(now, u.tim);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(mp[i][j] == '#' && !vis[i][j]){
return;
}
}
}
ans = min(ans, now);
}
int main(){
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
for(int _=1;_<=t;_++){
cin >> n >> m;
tot = 0;
ans = INT_MAX;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> mp[i][j];
if(mp[i][j] == '#'){
s[tot].x = i;
s[tot].y = j;
tot += 1;
}
}
}
for(int i=0;i<tot;i++){
for(int j=i+1;j<tot;j++){
memset(vis, 0, sizeof vis);
bfs(s[i].x, s[i].y, s[j].x, s[j].y);
}
}
for(int i=0;i<tot;i++){
memset(vis, 0, sizeof vis);
bfs(s[i].x, s[i].y, s[i].x, s[i].y);
}
cout << "Case " << _ << ": ";
cout << (ans == INT_MAX ? -1 : ans) << '\n';
}
return 0;
}
10. UVA11264 Fire!
- 模拟,用两个队列存一下
#include <bits/stdc++.h>
using namespace std;
struct st{
int x, y, tim;
};
int xx[] = {1, 0, -1, 0};
int yy[] = {0, 1, 0, -1};
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
int n, m;
cin >> n >> m;
vector<vector<char> > mp(n + 1, vector<char> (m + 1));
vector<vector<int> > vv(n + 1, vector<int> (m + 1));
vector<int> vis(10000);
int a, b;
vector<pair<int, int> > vs;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> mp[i][j];
if(mp[i][j] == 'J'){
a = i;
b = j;
}
if(mp[i][j] == 'F'){
vs.push_back(make_pair(i, j));
}
}
}
function<int()> Bfs = [&](){
queue<st> q;
st now;
q.push(st{a, b, 0});
queue<st> fire;
queue<st> q2;
for(auto i : vs){
fire.push(st{i.first, i.second, 0});
}
while(!q.empty()){
auto u = q.front();
q.pop();
if(!vis[u.tim]){
// for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++){
// cout << mp[i][j];
// }cout << '\n';
// }
while(!fire.empty()){
auto top = fire.front();
fire.pop();
int dx = top.x;
int dy = top.y;
for(int i=0;i<4;i++){
int x = dx + xx[i];
int y = dy + yy[i];
if(x < 1 || y < 1 || x > n || y > m || mp[x][y] == '#' || mp[x][y] == 'F') continue;
// cout << x << ' ' << y << '\n';
mp[x][y] = 'F';
q2.push(st{x, y, 0});
}
}
fire = q2;
vis[u.tim] = 1;
while(!q2.empty()){
q2.pop();
}
}
for(int i=0;i<4;i++){
int dx = u.x + xx[i];
int dy = u.y + yy[i];
if(dx < 1 || dy < 1 || dx > n || dy > m){
return u.tim + 1;
}
if(mp[dx][dy] == '#' || vv[dx][dy] || mp[dx][dy] == 'F') continue;
vv[dx][dy] = 1;
now.x = dx;
now.y = dy;
now.tim = u.tim + 1;
q.push(now);
}
}
return -1;
};
int ans = Bfs();
if(ans == -1){
cout << "IMPOSSIBLE" << '\n';
}else cout << ans << '\n';
}
return 0;
}
11. poj3984 迷宫问题
- 用数组记录路径,常规操作
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <map>
#include <iomanip>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
int a[MAXN];
int mp[10][10];
int xx[] = {1, 0};
int yy[] = {0, 1};
struct st{
int x, y;
int tim;
int ans_x[100];
int ans_y[100];
};
void bfs(){
st now;
now.x = 1;
now.y = 1;
now.tim = 0;
queue<st> q;
now.ans_x[0] = 0;
now.ans_y[0] = 0;
q.push(now);
while(!q.empty()){
now = q.front();
q.pop();
for(int i=0;i<2;i++){
int dx = now.x + xx[i];
int dy = now.y + yy[i];
if(dx < 1 || dy < 1 || dx > 5 || dy > 5 || mp[dx][dy] == 1) continue;
st top = now;
top.tim += 1;
top.x = dx;
top.y = dy;
top.ans_x[top.tim] = dx - 1;
top.ans_y[top.tim] = dy - 1;
if(dx == 5 && dy == 5){
for(int i=0;i<=now.tim;i++){
cout << '(' << now.ans_x[i] << ", " << now.ans_y[i] << ")\n";
}
cout << '(' << 4 << ", " << 4 << ")\n";
return;
}
q.push(top);
}
}
}
int main(){
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
for(int i=1;i<=5;i++){
for(int j=1;j<=5;j++){
cin >> mp[i][j];
}
}
bfs();
return 0;
}
12. hdu 1241
- 额,没什么好说的
#include <bits/stdc++.h>
using namespace std;
int xx[] = {1, 0, -1, 0, 1, 1, -1, -1};
int yy[] = {0, 1, 0, -1, 1, -1, -1, 1};
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
while(cin >> n >> m){
if(n == 0 && m == 0) break;
vector<vector<char> > a(n + 1, vector<char> (m + 1));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> a[i][j];
}
}
function<void(int, int)> Dfs = [&](int x, int y){
for(int i=0;i<8;i++){
int dx = x + xx[i];
int dy = y + yy[i];
if(dx < 1 || dy < 1 || dx > n || dy > m || a[dx][dy] == '*') continue;
a[dx][dy] = '*';
Dfs(dx, dy);
}
};
int ans = 0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j] == '@'){
ans += 1;
Dfs(i, j);
}
}
}
cout << ans << '\n';
}
return 0;
}
13. hdu 1495 非常可乐
- 搜索模拟六种可能的倒水方案,我写的比较麻烦可能,应该有不易错的写法,但是练习就要练最不会的东西
- 似乎有数论解法,求 s , n , m s,n,m s,n,m的 g c d gcd gcd,然后都除掉最后看 s s s的奇偶,如果是偶数答案就是 s − 1 s-1 s−1,虽然巧妙,但是想到或者算出来可能不太简单,如果赛场上遇到这样的问题搜索应该是比较靠谱的办法,如果打表找规律还不如写搜索
#include <bits/stdc++.h>
using namespace std;
struct st{
int s, n, m, tim;
};
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int s, n, m;
while(cin >> s >> n >> m){
if(s == 0 && n == 0 && m == 0) break;
vector<vector<vector<int> > > book(s + 1, vector<vector<int> > (n + 1, vector<int> (m + 1)));
function<int()> Bfs = [&](){
queue<st> q;
st now;
q.push(st{s, 0, 0, 0});
book[s][0][0] = 1;
while(!q.empty()){
auto u = q.front();
q.pop();
// queue<st> q2;
// q2 = q;
// while(!q2.empty()){
// auto v = q2.front();
// cout << v.s << ' ' << v.n << ' ' << v.m << ' ' << v.tim << '\n';
// q2.pop();
// }
// cout << '\n';
if(u.m == s / 2 && (u.n == 0 || u.s == 0)){
// cout << u.m << ' ' << u.n << ' ' << u.s << '\n';
return u.tim;
}
if(u.n == s / 2 && (u.s == 0 || u.m == 0)){
return u.tim;
}
if(u.s == s / 2 && (u.n == 0 || u.m == 0)){
return u.tim;
}
now.tim = u.tim + 1;
if(u.s > 0){
if(u.n < n){
int res = n - u.n;
if(res > u.s){
now.s = 0;
now.n = u.n + u.s;
now.m = u.m;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}else if(res > 0){
now.s = u.s - res;
now.n = n;
now.m = u.m;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}
}
if(u.m < m){
int res = m - u.m;
if(res > u.s){
now.s = 0;
now.n = u.n;
now.m = u.m + u.s;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}else if(res > 0){
now.s = u.s - res;
now.n = u.n;
now.m = m;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}
}
}
if(u.n > 0){
if(u.s < s){
int res = s - u.s;
if(res > u.n){
now.n = 0;
now.s = u.s + u.n;
now.m = u.m;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}else if(res > 0){
now.s = s;
now.n = u.n - res;
now.m = u.m;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}
}
if(u.m < m){
int res = m - u.m;
if(res > u.n){
now.n = 0;
now.s = u.s;
now.m = u.m + u.n;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}else if(res > 0){
now.n = u.n - res;
now.m = m;
now.s = u.s;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}
}
}
if(u.m > 0){
if(u.s < s){
int res = s - u.s;
if(res > u.m){
now.m = 0;
now.n = u.n;
now.s = u.s + u.m;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}else if(res > 0){
now.s = s;
now.n = u.n;
now.m = u.m - res;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}
}
if(u.n < n){
int res = n - u.n;
if(res > u.m){
now.m = 0;
now.s = u.s;
now.n = u.n + u.m;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}else if(res > 0){
now.m = u.m - res;
now.n = n;
now.s = u.s;
if(!book[now.s][now.n][now.m]){
q.push(now);
book[now.s][now.n][now.m] = 1;
}
}
}
}
}
return -1;
};
if(s & 1) cout << "NO" << '\n';
else{
int ans = Bfs();
if(ans != -1) cout << ans << '\n';
else cout << "NO" << '\n';
}
}
return 0;
}
14. hdu 2612 Find a way
- 记录一下KFC的位置,跑两次bfs找到每个人到KFC的距离,遍历每一个KFC取最小值即可
#include <bits/stdc++.h>
using namespace std;
struct st{
int x, y;
int tim;
};
int xx[] = {1, 0, -1, 0};
int yy[] = {0, 1, 0, -1};
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
while(cin >> n >> m){
vector<vector<char> > a(n + 1, vector<char> (m + 1));
int x1, y1, x2, y2;
vector<pair<int, int> > at;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> a[i][j];
if(a[i][j] == 'Y'){
x1 = i;
y1 = j;
}
if(a[i][j] == 'M'){
x2 = i;
y2 = j;
}
if(a[i][j] == '@'){
at.push_back(make_pair(i, j));
}
}
}
int ans = INT_MAX;
vector<vector<int> > vis1(n + 1, vector<int> (m + 1));
vector<vector<int> > vis2(n + 1, vector<int> (m + 1));
vector<vector<int> > dis1(n + 1, vector<int> (m + 1, INT_MAX));
vector<vector<int> > dis2(n + 1, vector<int> (m + 1, INT_MAX));
function<void(vector<vector<int> > &, vector<vector<int> > &, int, int)> Bfs = [&](vector<vector<int> > &vis, vector<vector<int> > &dis, int x0, int y0){
queue<st> q;
st x, now;
x.x = x0;
x.y = y0;
x.tim = 0;
q.push(x);
while(!q.empty()){
x = q.front();
q.pop();
for(int i=0;i<4;i++){
int dx = x.x + xx[i];
int dy = x.y + yy[i];
if(dx < 1 || dy < 1 || dx > n || dy > m || a[dx][dy] == '#' || vis[dx][dy]) continue;
vis[dx][dy] = 1;
now.x = dx;
now.y = dy;
now.tim = x.tim + 11;
if(a[dx][dy] == '@'){
dis[dx][dy] = now.tim;
}
q.push(now);
}
}
};
Bfs(vis1, dis1, x1, y1);
Bfs(vis2, dis2, x2, y2);
for(auto i : at){
if(dis1[i.first][i.second] != INT_MAX && dis2[i.first][i.second] != INT_MAX)
ans = min(ans, dis1[i.first][i.second] + dis2[i.first][i.second]);
}
cout << ans << '\n';
}
return 0;
}