HDU-1401

今天两道题都没AC出来 不过还是学到很多东西的

先放一下错误代码 :

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

int start[8];
int goal[8];

struct node {
    int checkedboard[8];
    int foot = 0;
};

bool check(int x, int y, int arr[]) {
    if (x >= 0 && x < 8 && y >= 0 && y < 8) {
        for (int i = 0; i < 4; i++) {
            if (arr[2 * i] == x && arr[2 * i + 1] == y) return false;
        }
        return true;
    }
    return false;
}

int dir[4][2] = {
    {1, 0},
    {-1, 0},
    {0, 1},
    {0, -1}
};

vector<int> get_sorted_state(int arr[]) {
    vector<pair<int, int>> coords;
    for (int i = 0; i < 4; i++) {
        coords.push_back({ arr[2 * i], arr[2 * i + 1] });
    }
    sort(coords.begin(), coords.end());
    vector<int> sorted_state;
    for (const auto& p : coords) {
        sorted_state.push_back(p.first);
        sorted_state.push_back(p.second);
    }
    return sorted_state;
}

bool bfs() {
    node start_node, goal_node;
    memcpy(start_node.checkedboard, start, sizeof(start_node.checkedboard));
    memcpy(goal_node.checkedboard, goal, sizeof(goal_node.checkedboard));

    queue<node> q_start, q_goal;
    q_start.push(start_node);
    q_goal.push(goal_node);

    set<vector<int>> visited_start, visited_goal;
    visited_start.insert(get_sorted_state(start_node.checkedboard));
    visited_goal.insert(get_sorted_state(goal_node.checkedboard));

    while (!q_start.empty() && !q_goal.empty()) {
        if (q_start.size() > q_goal.size()) {
            swap(q_start, q_goal);
            swap(visited_start, visited_goal);
        }

        int size = q_start.size();
        for (int i = 0; i < size; i++) {
            node n = q_start.front();
            q_start.pop();

            vector<int> current_state = get_sorted_state(n.checkedboard);
            if (visited_goal.find(current_state) != visited_goal.end()) {
                return true;
            }

            if (n.foot > 8) continue;

            for (int i = 0; i < 4; i++) {
                int x = n.checkedboard[2 * i];
                int y = n.checkedboard[2 * i + 1];
                for (int j = 0; j < 4; j++) {
                    node new_node;
                    memcpy(&new_node, &n, sizeof(struct node));
                    new_node.foot++;
                    int newx = x + dir[j][0];
                    int newy = y + dir[j][1];
                    if (check(newx, newy, n.checkedboard)) {
                        new_node.checkedboard[2 * i] = newx;
                        new_node.checkedboard[2 * i + 1] = newy;
                        vector<int> new_state = get_sorted_state(new_node.checkedboard);
                        if (visited_start.find(new_state) == visited_start.end()) {
                            visited_start.insert(new_state);
                            q_start.push(new_node);
                        }
                    }
                    else {
                        int jumpx = newx + dir[j][0];
                        int jumpy = newy + dir[j][1];
                        if (check(jumpx, jumpy, n.checkedboard)) {
                            new_node.checkedboard[2 * i] = jumpx;
                            new_node.checkedboard[2 * i + 1] = jumpy;
                            vector<int> new_state = get_sorted_state(new_node.checkedboard);
                            if (visited_start.find(new_state) == visited_start.end()) {
                                visited_start.insert(new_state);
                                q_start.push(new_node);
                            }
                        }
                    }
                }
            }
        }
    }
    return false;
}

int main() {
    while (cin >> start[0]) {
        for (int i = 1; i < 8; i++)
            cin >> start[i];
        for (int i = 0; i < 8; i++)
            cin >> goal[i];
        if (bfs()) {
            cout << "YES" << endl;
        }
        else {
            cout << "NO" << endl;
        }
    }
    return 0;
}

关键点:

使用双向广搜:降低时间复杂度 一个搜索4步即可 因为5 3 可以转换为4 4 不缺情况

使用sort排序:否则visited会有大量重复状态

四个点四个方向注意判断是否可以跳

使用八维数组记录坐标

下面是大神的代码:

#include<iostream>
#include<algorithm>
#include<string>
#include<stack>
#include<queue>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
#include<math.h>
 
#define eps 1e-9
#define P system("pause")
using namespace std;
struct point {
   int x,y;     
   friend bool operator<(point a,point b)
   {
       if(a.x!=b.x) return a.x<b.x;
       return a.y<b.y;       
   }  
};
struct node
{
     point s[4];   //记录四个棋子的位置 
     int step;     
};
char hash[8][8][8][8][8][8][8][8];        //如果是1则q1中的节点经过了,2则q2中的节点经过了,0表示为经过 
queue<node> q1,q2;
int d[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
 
void setflag(node a,char k)
{
       hash[a.s[0].x][a.s[0].y][a.s[1].x][a.s[1].y][a.s[2].x][a.s[2].y][a.s[3].x][a.s[3].y]=k;   
}
 
char getflag(node a)
{
     return  hash[a.s[0].x][a.s[0].y][a.s[1].x][a.s[1].y][a.s[2].x][a.s[2].y][a.s[3].x][a.s[3].y];    
}
 
bool judge(node &t,int i,int j,int m)                 //这个写的很巧妙,自己也写了个,总是wa,最后还是跟着答案写了
{
    if( m==1 )
   {
       if( t.step >=4 )//最多移动4步 
           return false;
       t.step ++;    
   }   
    
   t.s[i].x += d[j][0];
   t.s[i].y += d[j][1];
    if( t.s[i].x >= 0 && t.s[i].x < 8 && t.s[i].y >=0 && t.s[i].y<8 )
    {     int k;
          for(k=0; k<4 ; k++)
          {                 
             if(i!=k)
             {
                  if( t.s[i].x==t.s[k].x&&t.s[i].y==t.s[k].y )
                  if(m == 1) return judge(t, i , j , 2);
                  else return false;         
             }                      
          }
         if( k>=4 )
       { 
         sort( t.s , t.s + 4 );
         return true;
       } 
    } 
   return false;
}
 
 
bool dbfs()
{
       int i,j;
       char k;    
       node u;
       while(!q1.empty()||!q2.empty())
       {
             if(!q1.empty())
             {                            
                   for(i=0;i<4;i++)
                      for(j=0;j<4;j++)
                      {
                           u=q1.front();           
                           if(judge(u,i,j,1)){
                               k=getflag(u);
                               if(k==2) return 1;
                                else if(k==0){
                                     sort(u.s,u.s+4);        
                                     setflag(u,1);
                                     q1.push(u);
                                }
                           }            
                      }
                  q1.pop();                  
             }
             if(!q2.empty())
             {
                  for(i=0;i<4;i++)
                      for(j=0;j<4;j++)
                      {
                            u=q2.front();
                            if(judge(u,i,j,1)){   //判断可行,主要求u 
                                 k=getflag(u);
                                 if(k==1) return 1;
                                 else if(k==0) {
                                     sort(u.s,u.s+4);
                                     setflag(u,2);
                                     q2.push(u);    
                                 }                     
                            }                                 
                      }                       
                  q2.pop();
             }
       }     
       return 0;
}
 
 
 
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);cc
    int i,j;
    node A,B;
    while(scanf("%d%d",&i,&j)!=EOF)
    {
          memset(hash,0,sizeof(hash));                         
          while(!q1.empty()) q1.pop(); 
          while(!q2.empty()) q2.pop();                        
          i--;j--;
          A.s[0].x=i; A.s[0].y=j;
          for(i=1;i<4;i++){
              scanf("%d%d",&A.s[i].x,&A.s[i].y);
              A.s[i].x--;A.s[i].y--;
          }
          sort(A.s,A.s+4);
          setflag(A,1);
          for(i=0;i<4;i++){
              scanf("%d%d",&B.s[i].x,&B.s[i].y);
              B.s[i].x--;B.s[i].y--;
          } 
          sort(B.s,B.s+4);
          setflag(B,2);
          A.step=B.step=0;
          q1.push(A);
          q2.push(B);
          if(dbfs())  printf("YES\n");
          else printf("NO\n"); 
 
                                   
    }                         
 
  //  P;                               
    return 0;    
}

这个judge函数写的实在是太好了 真的简单明了:

大概意思为我有 1正常状态 2跳跃状态

当我为1 检查是否超出步数 return false 然后更新node查看是否越界 再分两种情况有重合和无重合在正常状态有就变跳跃 没就继续 跳跃状态没有就true 有就false 最后排序;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值