Codeforces 106 D Treasure Island

题目链接~~>

做题感悟:这题做着很有感觉,从超时一直优化改到AC。

解题思路:

这题如果不预先处理图的话,单纯的模拟肯定超时,so ~需要预先处理图,因为向 N 和 S 是 y 不变,x 变化,向 W 和 E x 不变 ,变 y . 这样可以用两个 vector 然后分别存x 不变的时候 y 的值,y 不变的时候 x 的值,这样查询的时候直接固定 x ,或者 y 然后找变化的。复杂度为最大为 26 * 1000 * 1000 。

代码:

#include<iostream>
#include<sstream>
#include<map>
#include<cmath>
#include<fstream>
#include<queue>
#include<vector>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<stack>
#include<bitset>
#include<ctime>
#include<string>
#include<iomanip>
#include<algorithm>
using namespace std  ;
#define INT __int64
const int INF = 99999999 ;
const double esp = 0.0000000001 ;
const double PI = acos(-1.0) ;
const int MY = 100000 + 5 ;
const int MX = 1000 + 5 ;
int n ,m ,num ,Q ,Gnum ;
char s[MX][MX] ,s1[50] ;
int dx[4] = {-1 ,1 ,0 ,0} ,dy[4] = {0 ,0 ,-1 ,1} ; // N ,S ,W ,E
vector<int>Gx[MX] ,Gy[MX] ;
struct node // 存景点
{
    char ch ;
    int x ,y ;
}T[50] ;
struct move // 各条指令
{
    int dir ,step ;
}Move[MY] ;
void input()
{
    int x ,y ;
    num = 0 ; // 记录景点个数
    Gnum = 0 ;// 记录 # 的个数
    for(int i = 0 ;i < n ; ++i)
    {
        scanf("%s" ,s[i]) ;
        for(int j = 0 ;j < m ; ++j)
          if(s[i][j] >= 'A' && s[i][j] <= 'Z') // 是景点
          {
             T[num].x = i ;
             T[num].y = j ;
             T[num++].ch = s[i][j] ;
          }
          else if(s[i][j] == '#') // 是墙
          {
              Gx[i].push_back(j) ;
              Gy[j].push_back(i) ;
          }
    }
    scanf("%d" ,&Q) ;
    char ch ;
    for(int i = 0 ;i < Q ; ++i) // 输入指令
    {
        cin>>ch>>x ;
        if(ch == 'N')
                y = 0 ;
        else if(ch == 'S')
                y = 1 ;
        else if(ch == 'W')
                y = 2 ;
        else    y = 3 ;
        Move[i].dir = y ; // 记录指令
        Move[i].step = x ;
    }
}
bool solve(int x ,int y)
{
    int sx ,sy ,dir ,step ,mt ;
    for(int i = 0 ;i < Q ; ++i) // 一次执行 Q 条指令
    {
        dir = Move[i].dir ;
        step = Move[i].step ;
        if(!dir) // N    y 不变 上
        {
            sx = x + dx[dir]*step ;
            mt = Gy[y].size() ;
            if(sx < 0 || sx >= n)  return false ; // 出界
            for(int j = 0 ;j < mt ; ++j)
              if(Gy[y][j] >= sx && Gy[y][j] < x)
                   return false ;
            x = sx ;
        }
        else if(dir == 1) // S 下  y 不变
        {
            sx = x + dx[dir]*step ;
            mt = Gy[y].size() ;
            if(sx < 0 || sx >= n)  return false ; // 出界
            for(int j = 0 ;j < mt ; ++j)
              if(Gy[y][j] > x && Gy[y][j] <= sx)
                   return false ;
            x = sx ;
        }
        else if(dir == 2) // W 左  x 不变
        {
            sy = y + dy[dir]*step ;
            mt = Gx[x].size() ;
            if(sy < 0 || sy >= m)  return false ;
            for(int j= 0 ;j < mt ; ++j)
              if(Gx[x][j] < y && Gx[x][j] >= sy)
                   return false ;
            y = sy ;
        }
        else  // E 右  x 不变
        {
            sy = y + dy[dir]*step ;
            mt = Gx[x].size() ;
            if(sy < 0 || sy >= m)  return false ;
            for(int j= 0 ;j < mt ; ++j)
              if(Gx[x][j] > y && Gx[x][j] <= sy)
                   return false ;
            y = sy ;
        }
    }
    return true ;
}
int main()
{
    while(~scanf("%d%d" ,&n ,&m))
    {
        input() ;
        int nx = 0 ;
        bool flag = false ;
        for(int i = 0 ;i < num ; ++i)
          if(solve(T[i].x ,T[i].y)) // 判断此起点是否合法
            {
               flag = true ;
               s1[nx++] = T[i].ch ;
            }
        if(flag)
        {
            s1[nx] = '\0' ;
            stable_sort(s1 ,s1+nx) ;
            cout<<s1<<endl ;
        }
        else   cout<<"no solution"<<endl ;
        for(int i = 0 ;i < Gnum ; ++i)
        {
            Gx[i].clear() ;
            Gy[i].clear() ;
        }
    }
    return 0 ;
}
时间: 2024-08-11 16:22:57

Codeforces 106 D Treasure Island的相关文章

Gym 100971A Treasure Island BFS 思维题

A - Treasure Island Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Description standard input/output Announcement Statements Pirate John Silver has found a map depicting exactly one island in a sea. The ma

Codeforces 106 C Buns【多重背包】

今天拉了一场CF,做了一下,略坑啊...首先105A题,竟然卡精度,小数点两位卡精度,需要给他加一个1e-6,算是见识了 题目:Codeforces 106 C Buns 题意:给出一些n克面,以及m种馅儿,每种馅儿做面包需要的面的克数和馅儿的克数以及馅儿的总克数,面也可以单独做面包,然后每一种面包都有价格,求做的面包的总价格最高? 分析:很贱的题目啊,读了之后就开始贪心,贪心竟然过了10组数据,然后我以为有漏洞,后来发现是个多重背包.dp的题目最怕用贪心做了,幸亏发现了. 标准的多种背包,转化

Codeforces 106D Treasure Island

题目链接:点击打开链接 题意: 给定n*m的矩阵 # 是墙 . 和字母是平地 最多有26个字母(不重复出现) 下面k个指令, 每个指令代表移动的方向和步数. 若以某个字母为起点,依次执行所有的指令,任何过程都不会撞到墙或走出地图,则这个字母合法. 按字典序输出所有合法的字母.若没有字母合法则输出' no solution' 预处理一下前缀和然后暴力. #include <cstdio> #include <iostream> #include <algorithm> #

Codeforces Round #583 (Div. 1 + Div. 2, based on Olympiad of Metropolises), problem: (D) Treasure Island

题目大意 给你一个n*m 的棋盘 有的地方不能过 问题最少需要堵多少次 才能让(1,1)到(n,m)没有路径通过 解法: 打表发现 对角线最后剩下的通路最少 即为答案 画图可知$ 2*2$的子矩形内 右对角线被填满时左对角线都不能到达 递推判断即可 细节蛮多的 code: #include<stdio.h> #include<iostream> #include<cstring> #include<cmath> #include<stdio.h>

Codeforces GYM 100114 B. Island 水题

B. Island Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Description On February 30th this year astronauts from the International Space Station flew over the Pacific Ocean and took a picture, on which was discovered a pr

CodeForces 540D Bad Luck Island 概率dp

CodeForces 540D 应该是简单概率dp,由于写得少显得十分蠢萌 求期望逆推,求概率正推,大概是这么个意思,贴一发留恋 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define db double const int maxn=108; db dp[maxn][maxn][maxn]; int main() { int i,j,n,m,k,p; whi

Codeforces 540D Bad Luck Island

http://codeforces.com/problemset/problem/540/D 题目大意: 会出石头.剪刀.布的人分别有r,s,p个,他们相互碰到的概率相同,输的人死掉,问最终活下去的人是三种类型的概率. 思路: f[i][j][k]代表i个石头,j个剪刀,k个布状态的概率,初始f[n][m][K]=1 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstr

Codeforces 540D Bad Luck Island - 概率+记忆化搜索

[题意] 一个岛上有三种生物A,B,C,各有多少只在输入中会告诉你,每种最多100只 A与B碰面,A会吃掉B, B与C碰面,B会吃掉C, C与A碰面,C会吃掉A...忍不住想吐槽这种环形食物链 碰面是随机的.到最后岛上只剩下一种生物,问这种生物分别是A,B,C的概率是多少. [题解] 其实很简单,这题,状态方程很好想.. 设dp[i][j][k]为生物A有i只,生物B有j只,生物C有k只的概率情况,显然dp的返回值应该有三个,分别是最后剩下该种生物的概率 那么我们考虑状态转移的情况. 如果A与B

Codeforces 106 DIV2 ACD

B表示完全看不懂..就不弄了.. E字符串先不管了.到时候系统学下字符串再处理 A #include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include &