NOI openjudge 6043:哆啦A梦的时光机(双向宽搜)

在线评测:

http://noi.openjudge.cn/ch0407/6043/

整体思路:

这种题随便宽搜一下就好了,没啥思路可讲,,,,

失误之处:

1、开始脑子里想的是一面扩展一层,这样子可以保证答案最小,然后写着写着就脑残了,写成了一面扩展一个,,,

2、用vis表示一个点时候已经被扩展出来,然而开始我vis就全赋值成0,导致了起点和重点难以判断,会被误判断为没有被扩展过

3、然后又脑残了,再尝试扩展一层的时候,我不断地while,但是由于我的记录层数的队列里存的值是弹出后的那个点所扩展的次数,然而我while的时候却直接比较队首元素而没有+1,所以导致了无限的扩展,,,

4、傻×的我初始化的时候没有初始化起点和终点,,,

体会心得:

写代码的时候不要理所应当,应当想一想写出的代码和自己所想的代码一不一样,

注意起点终点的图书情况

明确变量含义,注意+1-1细节

AC代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
queue <int> dl1;
queue <int> js1;
queue <int> dl2;
queue <int> js2;
bool js;
int n,s,t,ans;
int vis1[3000000],vis2[3000000];
void kz1(int tp,int tc)
{
     if  (tp + 1 < 2000000 && vis1[tp+1] < 0)
     {
         if  (vis2[tp+1] >= 0) ans =  tc + vis2[tp+1] - 1,js =  true ;
         dl1.push(tp+1);
         js1.push(tc);
         vis1[tp+1] = tc - 1;
     }
     if  (tp - 1 > 0 && vis1[tp-1] < 0)
     {
         if  (vis2[tp-1] >= 0) ans = tc + vis2[tp-1] - 1,js =  true ;
         dl1.push(tp-1);
         js1.push(tc);
         vis1[tp-1] = tc - 1;
     }
     if  (tp * 2 < 2000000 && vis1[tp*2] < 0)
     {
         if  (vis2[2 * tp] >= 0) ans = tc + vis2[tp * 2] - 1,js =  true ;
         dl1.push(tp * 2);
         js1.push(tc);
         vis1[tp*2] = tc - 1;
     }
     if  (vis1[tp / 2] <0 && !(tp & 1))
     {
         if (vis2[tp /2] >= 0) ans = tc + vis2[tp / 2] - 1,js =  true ;
         dl1.push(tp/2 );
         js1.push(tc);
         vis1[tp/2] = tc - 1;
     }
}
void kz2(int tp,int tc)
{
     if  (tp + 1 < 2000000 && vis2[tp+1] < 0)
     {
         if  (vis1[tp+1] >= 0) ans = tc + vis1[tp + 1] - 1,js =  true ;
         dl2.push(tp+1);
         js2.push(tc);
         vis2[tp+1] = tc - 1;
     }
     if  (tp - 1 > 0 && vis2[tp-1] < 0)
     {
         if  (vis1[tp-1] >= 0) ans = tc + vis1[tp - 1] - 1,js =  true ;
         dl2.push(tp-1);
         js2.push(tc);
         vis2[tp-1] = tc - 1;
     }
     
     if  (tp * 2 < 2000000 && vis2[tp*2] < 0)
     {
         if  (vis1[2 * tp] >= 0) ans = tc + vis1[tp * 2] - 1,js =  true ;
         dl2.push(tp * 2);
         js2.push(tc);
         vis2[tp*2] = tc - 1;
     }
     if  (vis2[tp / 2] < 0 && !(tp&1))
     {
         if (vis1[tp /2] >= 0) ans = tc + vis1[tp/2] - 1,js =  true ;
         dl2.push(tp/2);
         js2.push(tc);
         vis2[tp/2] = tc - 1;
     }
}
int bfs(int s,int t)
{
     memset(vis1,-1,sizeof(vis1));
     memset(vis2,-1,sizeof(vis2));
     while  (!dl1.empty()) dl1.pop();
     while  (!dl2.empty()) dl2.pop();
     while  (!js1.empty()) js1.pop();
     while  (!js2.empty()) js2.pop();
     dl1.push(s);
     js1.push(1);
     dl2.push(t);
     js2.push(1);
     vis1[s] = 0;
     vis2[t] = 0;
     js =  false ;
     ans = 0;
     while  (1)
     {
         if  (dl1.size() < dl2.size())
         {
             int tp = dl1.front();
             dl1.pop();
             int tc = js1.front() + 1;
             js1.pop();
             kz1(tp,tc);
             if  (js)  return  ans;
             while  (!js1.empty() && tc == js1.front() + 1)
             {
                 tc = js1.front() + 1;
                 js1.pop();
                 tp = dl1.front();
                 dl1.pop();
                 kz1(tp,tc);
                 if  (js)  return  ans;
             }
         }
         else
         {
             int tp = dl2.front();
             dl2.pop();
             int tc = js2.front() + 1;
             js2.pop();
             kz2(tp,tc);
             if  (js)  return  ans;
             while  (!js2.empty() && tc == js2.front() + 1)
             {
                 tc = js2.front() + 1;
                 js2.pop();
                 tp = dl2.front();
                 dl2.pop();
                 kz2(tp,tc);
                 if  (js)  return  ans;
             }
         }
     }
}
void sread()
{
     scanf( "%d" ,&n);
     for  (int i = 1; i <= n; i++)
     {
         scanf( "%d%d" ,&s,&t);
         printf( "%d\n" ,bfs(s,t) * 2);
     }
}
int main()
{
     sread();
     return  0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值