「日常训练」Ice Cave(Codeforces Round 301 Div.2 C)

题意与分析(CodeForces 540C)

这题坑惨了我。。。。我和一道经典的bfs题混淆了,这题比那题简单。

那题大概是这样的,一个冰塔,第一次踩某块会碎,第二次踩碎的会掉落。然后求可行解。

但是这题。。。是冰塔的一层

也就是说,它只是个稍微有点限制的二维迷宫问题。

后面就好理解了,不过需要考虑下这种数据:

1 2
XX
1 1
1 1

这种数据答案是no。解决的方法可以考虑这样:分成两个数组来记录访问状态:vis数组和block数组。

代码

#include <queue>
#include <set>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#define MP make_pair
#define PB push_back
#define fi first
#define se second
#define ZERO(x) memset((x), 0, sizeof(x))
#define ALL(x) (x).begin(),(x).end()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define QUICKIO                      ios::sync_with_stdio(false);     cin.tie(0);                      cout.tie(0);
using namespace std;

bool iscracked[505][505];
bool vis[505][505];
set<pair<int,int> > s;

int bx,by,ex,ey,n,m;
const int dx[]={0,1,0,-1};
const int dy[]={1,0,-1,0};
bool bfs()
{
    queue<pair<int,int> > q;
    q.push(MP(bx,by));
    s.insert(MP(bx,by));
    iscracked[bx][by]=true;
    auto end_pair=MP(ex,ey);
    while(!q.empty())
    {
        auto now=q.front(); q.pop();
        if(now==end_pair && iscracked[now.fi][now.se] && vis[now.fi][now.se]) return true;
        //cout<<"NP: "<<now.fi<<" "<<now.se<<endl;
        iscracked[now.fi][now.se]=true;
        vis[now.fi][now.se]=true;
        rep(i,0,3)
        {
            int tx=now.fi+dx[i], ty=now.se+dy[i];
            if(tx>=1 && tx<=n && ty>=1 && ty<=m && (!iscracked[tx][ty]||(tx==ex&&ty==ey)))
            {
                auto tstat=MP(tx,ty);
                //cout<<"Trying to go"<<tx<<" "<<ty<<" "<<iscracked[tx][ty]<<endl;
                if(s.find(tstat)==s.end() || tstat==end_pair)
                {
                    //cout<<"    success"<<endl;
                    s.insert(tstat);
                    q.push(tstat);
                }
            }
        }
    }
    return false;
}

int main()
{
    cin>>n>>m;
    ZERO(iscracked);ZERO(vis);
    rep(i,1,n)
    {
        string str; cin>>str;
        rep(j,0,m-1)
        {
            iscracked[i][j+1]=vis[i][j+1]=str[j]==‘X‘;
        }
    }
    cin>>bx>>by>>ex>>ey;
    vis[bx][by]=false;
    //if(bx==ex && by==ey && n==1 && m==1)
    cout<<string(bfs()?"YES":"NO")<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/samhx/p/cfr301d2c.html

时间: 2024-10-07 16:05:57

「日常训练」Ice Cave(Codeforces Round 301 Div.2 C)的相关文章

「日常训练」Woodcutters(Codeforces Round 303 Div.2 C)

这题惨遭被卡..卡了一个小时,太真实了. 题意与分析 (Codeforces 545C) 题意:给定\(n\)棵树,在\(x\)位置,高为\(h\),然后可以左倒右倒,然后倒下去会占据\([x-h,x]\)或者\([x,x+h]\)区间,如果不砍伐,占据\([x,x]\)区域. 问你最多砍多少棵树,砍树的条件是倒下去后占有的区间不能被其他树占据. 分析:在这条题目的条件下,这是一个傻逼贪心题.(然后我读错两次题目,怎么也想不出来贪心策略....) 很简单的策略:能往左倒往左倒,能往右倒往右倒.因

「日常训练」Skills(Codeforce Round Div.2 #339 D)

题意(CodeForces 614D) 每个人有\(n(n\le 10^5)\)个技能,技能等级都在\([0,10^9]\)的范围,每个技能有一个当前等级,所有技能的最高等级都为A.一个人的力量被记做以下两项的和: 1. 顶级技能的个数 *cf 2. 最低等级的技能 *cm 每个单位的钱能够提升一级力量.我们希望花尽可能少的钱,使得力量尽可能高. 分析 我二分的功力还是不足,要多努力.这题其实是一个非常明显的暴力:我们枚举提高到A的等级的个数(到不能提升为止),枚举这种情况下,我们能够令把多少人

DFS/BFS Codeforces Round #301 (Div. 2) C. Ice Cave

题目传送门 1 /* 2 题意:告诉起点终点,踩一次, '.'变成'X',再踩一次,冰块破碎,问是否能使终点冰破碎 3 DFS:如题解所说,分三种情况:1. 如果两点重合,只要往外走一步再走回来就行了:2. 若两点相邻, 4 那么要不就是踩一脚就破了或者踩一脚走开再走回来踩一脚破了:3. 普通的搜索看是否能到达, 5 若能还是要讨论终点踩几脚的问题:) 6 DFS 耗时大,险些超时,可以用BFS来做 7 */ 8 #include <cstdio> 9 #include <algorit

Codeforces Round #301 (Div. 2) -- (A,B,C,D)

题目传送:Codeforces Round #301 (Div. 2) A. Combination Lock 水题,求最小移动次数,简单贪心一下即可 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #i

贪心 Codeforces Round #301 (Div. 2) A. Combination Lock

题目传送门 1 /* 2 贪心水题:累加到目标数字的距离,两头找取最小值 3 */ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <cstring> 8 using namespace std; 9 10 const int MAXN = 1e3 + 10; 11 const int INF = 0x3f3f3f3f; 12 char s[MAXN],

贪心 Codeforces Round #301 (Div. 2) B. School Marks

题目传送门 1 /* 2 贪心:首先要注意,y是中位数的要求:先把其他的都设置为1,那么最多有(n-1)/2个比y小的,cnt记录比y小的个数 3 num1是输出的1的个数,numy是除此之外的数都为y,此时的numy是最少需要的,这样才可能中位数大于等于y 4 */ 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <cstring> 9 using na

CodeForces Round #301 Div.2

今天唯一的成果就是把上次几个人一起开房打的那场cf补一下. A. Combination Lock 此等水题看一眼样例加上那个配图我就明白题意了,可是手抽没有注释掉freopen,WA了一发. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 1000 + 10; 5 6 char s1[maxn], s2[maxn]; 7 8 int main() 9 { 10 int n; cin >>

【解题报告】Codeforces Round #301 (Div. 2) 之ABCD

A. Combination Lock 拨密码..最少次数..密码最多有1000位. 用字符串存起来,然后每位大的减小的和小的+10减大的,再取较小值加起来就可以了... #include<stdio.h> #include<math.h> #include<string.h> #include<iostream> #include<algorithm> #include<map> #include<set> #inclu

C. Ice Cave (CF #301 (Div. 2) 搜索bfs)

C. Ice Cave time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You play a computer game. Your character stands on some level of a multilevel ice cave. In order to move on forward, you need to