15nod1572-模拟&前缀和&枚举-宝岛地图

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1572
中文题意,恕不赘述。
枚举每个点dfs的时候t了。开始每看懂题意。以为只要判断转折点就行了,后来发现只要再点到点的过程种也不能有#出现qwq
技巧:为了避免再转折的时候再判断路径种的点,维护一下方向的前缀和。然后再搞就好了, 枚举是1e6,轻轻松松就可以达到。
注:我枚举的是包括自身的,计算的时候都应该-1再弄。

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+20;
int nor[maxn][maxn];
int sou[maxn][maxn];
int eas[maxn][maxn];
int wes[maxn][maxn];
char a[maxn][maxn];
int m,n;
bool flag;
vector<pair<char,int> >p;
vector<char>q;
void dfs(int i,int j,int siz){
     if(siz==p.size())
     {   flag=true;
        //puts("!!!!!");
          return ;
     }
     if(p[siz].first=='N'){
        if((nor[i][j]-1)>=p[siz].second){
            dfs(i-p[siz].second,j,siz+1);

        }
     }
     else if(p[siz].first=='S'){
        if((sou[i][j]-1)>=p[siz].second)
            dfs(i+p[siz].second,j,siz+1);
            //cout<<i<<" "<<j<<p[siz].second<<endl;
     }
      else if(p[siz].first=='W'){
        if((wes[i][j]-1)>=p[siz].second)
            dfs(i,j-p[siz].second,siz+1);
            //cout<<i<<" "<<j<<p[siz].second<<endl;
      }
      else if(p[siz].first=='E'){
        if((eas[i][j]-1)>=p[siz].second)
            dfs(i,j+p[siz].second,siz+1);
            //cout<<i<<" "<<j<<p[siz].second<<endl;
     }

}
int main()
{   while(~scanf("%d%d",&m,&n)){
          for(int i=1;i<=m;i++){
              for(int j=1;j<=n;j++)
                  cin>>a[i][j];
          }
          memset(sou,0,sizeof(sou));
          for(int i=m;i>=1;i--){
              for(int j=1;j<=n;j++){
                    if(a[i][j]!='#')
                       sou[i][j]=sou[i+1][j]+1;
                    else
                        sou[i][j]=0;
              }
          }
          memset(nor,0,sizeof(nor));
          for(int i=1;i<=m;i++){
             for(int j=1;j<=n;j++){
                 if(a[i][j]!='#')
                    nor[i][j]=nor[i-1][j]+1;
                 else
                    nor[i][j]=0;
             }
          }
          memset(eas,0,sizeof(eas));
          for(int i=1;i<=m;i++){
              for(int j=n;j>=1;j--)
                 if(a[i][j]!='#')
                    eas[i][j]=eas[i][j+1]+1;
                 else
                    eas[i][j]=0;
          }
          memset(wes,0,sizeof(wes));
          for(int i=1;i<=m;i++){
              for(int j=1;j<=n;j++)
                 if(a[i][j]!='#')
                    wes[i][j]=wes[i][j-1]+1;
                 else
                    wes[i][j]=0;
          }
          //cout<<sou[2][4]<<endl;
          /*for(int i=1;i<=m;i++){
             for(int j=1;j<=n;j++){
                  if(a[i][j]>='A'&&a[i][j]<='Z')
                     printf("%c %d %d %d %d\n",a[i][j],nor[i][j],sou[i][j],wes[i][j],eas[i][j]);

             }
          }*/
          int num1;
          cin>>num1;
          p.clear();
          int num2;char cha;
          for(int i=0;i<num1;i++){
             cin>>cha>>num2;
             p.push_back(make_pair(cha,num2));
          }
          //cout<<"**"<<endl;
          q.clear();
          for(int i=1;i<=m;i++){
             for(int j=1;j<=n;j++){
                 if(a[i][j]>='A'&&a[i][j]<='Z'){
                     flag=false;
                     //cout<<a[i][j]<<endl;
                     dfs(i,j,0);
                     if(flag)
                        q.push_back(a[i][j]);
                 }

             }
          }
          sort(q.begin(),q.end());
          if(q.size()!=0){
          for(int i=0;i<q.size();i++){
              printf("%c",q[i]);
          }
          cout<<endl;
          }
          else
            puts("no solution");
    }
    return 0;
}

附赠tle版本
看着就不像能a的。。只是想rush一下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+200;
char s[maxn][maxn];
int m,n;
int fx[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
vector<pair<char,int> >q;
vector<char>re;
int flag;
void dfs(int x,int y,int siz){
     if(flag!=-1) return;
     if(x>m||x<1||y>n||y<1)
       {flag=0;
       //cout<<"**"<<endl;
       return;}
      if(siz==q.size()&&(s[x][y]=='.'||(s[x][y]>='A'&&s[x][y]<='Z'))){
          flag=1;return;
      }
      if(q[siz].first=='N'){
         for(int i=0;i<=q[siz].second;i++)
            if(s[x-i][y]=='#'||x-i<1){flag=0;
            //cout<<s[x-i][y]<<" "<<i<<endl;
            //cout<<"n"<<endl;
            break;}
            dfs(x-q[siz].second,y,siz+1);
         }
      else if(q[siz].first=='S'){
          for(int i=0;i<=q[siz].second;i++)
            if(s[x+i][y]=='#'||x+i>m){flag=0;
            //cout<<"s"<<endl;
            break;}
          dfs(x+q[siz].second,y,siz+1);

          }
      else if(q[siz].first=='W'){
          for(int i=0;i<=q[siz].second;i++)
            if(s[x][y-i]=='#'||y-i<1){flag=0;
            //cout<<"w"<<endl;
            break;}
          dfs(x,y-q[siz].second,siz+1);
          }
      else{
          for(int i=0;i<=q[siz].second;i++)
            if(s[x][y+i]=='#'||y+i>n){flag=0;
              //cout<<s[x+i][y]<<" "<<x<<endl;
            //cout<<"e"<<endl;break;
            }
          dfs(x,y+q[siz].second,siz+1);
      }
 }
int main()
{   while(cin>>m>>n){
          re.clear();
          q.clear();
          for(int i=1;i<=m;i++){
              for(int j=1;j<=n;j++){
                 cin>>s[i][j];
              }
          }
          int num;
          cin>>num;
          char cha;int num1;
          for(int i=1;i<=num;i++){
             cin>>cha>>num1;
             q.push_back(make_pair(cha,num1));
          }
          //reverse(q.begin(),q.end());
          for(int i=1;i<=m;i++){
              for(int j=1;j<=n;j++){
                  if(s[i][j]>='A'&&s[i][j]<='Z')
                  {  flag=-1;
                      dfs(i,j,0);
                      //if(s[i][j]=='A')
                        //cout<<flag<<"!!"<<endl;
                      if(flag==1)
                        re.push_back(s[i][j]);
                  }
              }
          }
          sort(re.begin(),re.end());
          if(re.size()!=0){
              //printf("%d\n",re.size());
              for(int i=0;i<re.size();i++){
                  printf("%c",re[i]);
              }
              cout<<endl;
          }
          else
            puts("no solution");
}
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值