CF128A Statues 解题报告

本文介绍了Codeforces平台上的CF128A问题,即一个8x8棋盘游戏,玩家玛丽亚需要避开雕像到达安娜的位置。在玛丽亚采取最优策略的情况下,分析了游戏的胜负条件。通过示例输入和输出解析了解题思路,并提供了三种不同的解决方案,涉及深度优先搜索和广度优先搜索算法。
摘要由CSDN通过智能技术生成

CF128A Statues 解题报告

1 题目链接

https://codeforces.com/problemset/problem/128/A

2 题目整理

题目 :雕像

题目描述

在这个任务中,安娜和玛丽亚与一个对手玩游戏。安娜和玛丽亚在棋盘对面的方格里(8 × 8) 当前位置安娜在右上角,玛丽亚在左下角。除此之外,棋盘上还有几座雕像。每尊雕像正好占据一个单元格。包含雕像的单元格上不能有任何东西或任何人——既不能有任何其他雕像,也不能有安娜或玛丽亚。

安娜在棋盘上是一个雕像(她一动不动,从不动),玛丽亚一直积极参与游戏。她的目标是——来到安娜广场。玛丽亚和雕像依次移动,玛丽亚先移动。在一次移动中,玛丽亚可以去任何相邻的没有雕像的侧边或对角牢房,或者她可以留在自己所在的牢房里。在移动过程中,雕像必须同时向下移动一个单元格,而那些位于最下面一排的雕像从板上掉落,不再出现。

在那一刻,当其中一尊雕像在玛丽亚所在的牢房里时,这些雕像被宣布为获奖者。当玛丽亚走进安娜一直在等待的牢房时,玛丽亚被宣布为获胜者。

显然,没有什么取决于雕像,所以一切都取决于玛丽亚。如果玛丽亚没有犯战略错误,确定谁会赢。

输入格式

给你8个字符串,长度等于8,描述了棋盘上的初始位置。第一行表示棋盘的顶行,下一行表示从顶部开始的第二行,依此类推,最后一行表示底行。每个字符串都与相应行中的单个单元格板匹配,并且字符的方式与相应单元格的方式相同。如果单元格为空,则相应的字符为“.”。如果一个单元格有Maria,那么它由字符“M”表示。如果一个单元格有安娜,它由字符“a”表示。如果一个单元有一个雕像,则该单元由字符“S”表示。

保证第一行的最后一个字符始终为“A”,最后一行的第一个字符始终为“M”。剩下的字符是“”或“S”。

输出格式

在Maria没有出现战略错误的情况下,赢了,请打印“WIN”(不带引号)。否则,请打印“LOSE”(不带引号)。

样例输入1
.......A
........
........
........
........
........
........
M.......

样例输出1
WIN
样例输入2
.......A
........
........
........
........
........
SS......
M.......
样例输出2
LOSE
样例输出3
.......A
........
........
........
........
.S......
S.......
MS......
样例输出3
LOSE
数据范围

数据保证A在右上角,M在左下角。

3 题意分析

3.1 题目大意

一个8×8的棋盘,Maria在左下角,Anna在右上角,Maria想到右上角(Anna的格子)。棋盘上还有很多雕塑。每次Maria移动完后,所有的雕塑都会向下一格,若雕塑已经在最后一行的话,再往下就会掉下棋盘。Maria不能碰到雕像。在Maria选择最优策略下,判断谁会赢。

3.2 样例分析

如上所述。

4 解法分析

这题最重要的就是雕像的移动。可以发现,当Maria移动了k步,到了(x1,y1)时,每个雕像就会向下移动k个格子。那么,在Maria移动了k步后,他需要考虑的不过是(x1, y1 + k)和(x1, y1 + k + 1)(因为下一步雕像会走下来)。
只要这两个格子没有雕像,就可以走。

同时,这道题还存在一个优化点:如果已经走了8步以上,说明盘上的所有雕像都掉完了,那么就一定可以到Anna。

AC代码

ACCode #001
// From Heart_Blue
// Rating 2425
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 10 + 10;
char board[N][N][N];
int flag[N][N][N];
int dx[] = { 0,0,0,1,1,1,-1,-1,-1 };
int dy[] = { 0,1,-1,1,-1,0,1,-1,0 };
int n, m;
bool dfs(int o, int x, int y)
{
	if (x < 0 || x >= n) return false;
	if (y < 0 || y >= m) return false;
	if (o >= 0 && board[o][x][y] == 'S') return false;
	o++;
	if (board[o][x][y] == 'S') return false;
	if (flag[o][x][y]) return false;
	flag[o][x][y] = 1;
	if (o == 8) return true;
	for (int i = 0; i < 9; i++)
	{
		if (dfs(o, x + dx[i], y + dy[i]))
			return true;
	}
	return false;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	MEM(board, '.');
	n = m = 8;
	for (int i = 0; i < 8; i++)
	{
		cin >> board[0][i];
	}
	board[0][7][0] = '.';
	board[0][0][7] = '.';
	for (int i = 1; i <= 8; i++)
	{
		for (int j = 1; j < 8; j++)
		{
			memcpy(board[i][j], board[i - 1][j - 1], sizeof(board[i][j]));
		}
	}
	if (dfs(-1, 7, 0)) puts("WIN");
	else puts("LOSE");
	return 0;
}
ACCode #002
// From Mahdi_Jfri
// Rating 2405
#include<bits/stdc++.h>
using namespace std;
#define ll long long
string s[10];
int a,b;
void dfs(int x,int y,int k)
{
    if(k > 6)
    {
        cout << "WIN";
        exit(0);
    }
    for(int i = -1; i < 2; i++)
        for(int j = -1; j < 2; j++)
        {
            a = x + i;
            b = y + j;
            if(a > 7 || b > 7 || a < 0 || b < 0)
                continue;
            if(a - k > -1 && (s[a-k][b] == 'S'))
                continue;
            if(a - k > 0 && s[a-k-1][b] == 'S')
                continue;
            dfs(a,b,k+1);
        }
}
int main()
{
    for(int i = 0; i < 8; i++)
        cin >> s[i];
    dfs(7,0,0);
    cout << "LOSE";
}
ACCode #003
// From xyf007
// Rating 2613
//********************************//
//****** Author : GEN.G ELVIN *******//
//****** Not T1's Fan anymore ******//
//********************************//
#include<bits/stdc++.h>
using namespace std;
#define Foe(it,c) for ( __typeof(c.begin()) it = c.begin(); it  != c.end(); it ++)
#define For(i,a,b) for (int i = a; i <= b; i++)
#define Fordown(i,a,b) for (int i = a; i >= b; i--)
#define each(a,b,c) if(a <= b && b <= c)
#define eol '\n'
#define pb push_back
#define fi first
#define se second
using db = double;
using ll = long long;
using pii = pair<int,int>;
using piii = pair<int,pii>;
using pll = pair<ll,ll>;
using pdi = pair<double,int>;
using vi = vector<int>;
using vl = vector<ll>;
using mii = map<int,int>;
const db pi = acos(-1.00);
const db eps = 1e-6;
const ll inf = 1e9;
const ll MOD = 999999998;;
const int base = 2333333;
const int dx[] = {-1, -1, -1, 0, 0, 0, 1, 1, 1, 1};
const int dy[] = {-1, 0, 1, -1, 0, 1, -1, -1, 0, 1};
const int Max = 1e5+1;
template<typename T> void maximize(T &res, const T &val) { if (res < val) res = val; }
template<typename T> void minimize(T &res, const T &val) { if (res > val) res = val; }

namespace IO{
    void fastio(){
        ios_base::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
    }
    void file(const string FILE = "Test") {
        freopen((FILE + ".INP").c_str(), "r", stdin);
        freopen((FILE + ".OUT").c_str(), "w", stdout);
    }
}

using namespace IO;

int n;
char a[33][9][9];
bool visited[33][9][9];
struct test_case {
    void read() {
        For(i,1,8) For(j,1,8) cin >> a[0][i][j];
        a[0][1][8] = a[0][8][1] = '.';
        For(t,1,32) {
            For(i,1,8) For(j,1,8) {
                if(i == 1) a[t][i][j] = '.';
                else a[t][i][j] = a[t-1][i - 1][j];
            }
        }
    }

    bool bfs() {
        queue<piii> q;
        q.push({0,{8,1}});
        visited[0][8][1] = true;
        while(!q.empty()) {
            int time = q.front().fi;
            int u = q.front().se.fi;
            int v = q.front().se.se;
            q.pop();
            if(u == 1 && v == 8) return true;
            if(time == 30) continue;
            For(i,0,9) {
                int new_u = u + dx[i];
                int new_v = v + dy[i];
                if(new_u < 1 || new_u > 8 || new_v < 1 || new_v > 8) continue;
                if(a[time + 1][new_u][new_v] == 'S' || a[time][new_u][new_v] == 'S') continue;
                if(visited[time + 1][new_u][new_v]) continue;
                visited[time + 1][new_u][new_v] = 1;
                q.push({time + 1,{new_u,new_v}});
            }
        }
        return false;
    }


    void solve() {
        if(bfs()) cout << "WIN";
        else cout << "LOSE";
    }
};


int main(void)
{
    fastio();
    //file("codeforces");
    int t = 1;
    //cin >> t;
    while(t--) {
        test_case task;
    	task.read();
    	task.solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值