用循环队列求解一个问题
F 神正在爬楼梯,他从第 0 级台阶出发,想要爬到第 P 级台阶。他一次可以爬的台阶数目
是固定的,为 a1, a2, ,, aN 这 N 个数中的一个。
由于年久失修,一共有 M 级台阶损坏了,分别为 b1, b2, , , bM 级台阶,如果走上这些台
阶,F 神就会坠落。
请问是否存在方案,使得 F 神能够爬到第 P 级台阶?
Input
输入共五行。
输入的第一行为一个正整数 N。
输入的第二行为 N 个正整数,第 i 个为 ai。
输入的第三行为一个正整数 M。
输入的第四行为 M 个正整数,第 i 个为 bi。
输入的第五行为 P。
Output
输出一行一个字符串,若可以爬到,输出 Yes,否则输出 No。
#include
#define MAXN 1000
int N;
int n[15];
int M;
int m[MAXN]={0};
int p;
int queue[MAXN];
int head=0,tail=0;
void push(int x){
if((tail+1)%MAXN==head){
return ;
}else{
tail=(tail+1)%MAXN;
queue[tail]=x;
}
}
int pop(void){
if(head==tail){
return 0;
} else{
head=(head+1)%MAXN;
return queue[head];
}
}
int main(){
scanf("%d",&N);
int i;
for(i=1;i<=N;i++){
scanf("%d",&n[i]);
}
scanf("%d",&M);
int t;
for(i=1;i<=M;i++){
scanf("%d",&t);
m[t]=1;
}
scanf("%d",&p);
queue[0]=0;
tail=1;
while(head!=tail && queue[head]int t=pop();
printf("t=%d head=%d tail =%d\n",t,head,tail);
for(i=1;i<=N;i++){
if(m[t+n[i]]==0){
push(t+n[i]);
m[t+n[i]]=1;
}
}
}
if(queue[head]==p){
printf("Yes");
}else{
printf("No");
}
return 0;
}
我在输入1 1 0 1050后
输出结果:
t=993 head=994 tail =995
t=994 head=995 tail =996
t=995 head=996 tail =997
t=996 head=997 tail =998
t=997 head=998 tail =999
t=998 head=999 tail =0
t=999 head=0 tail =0
No
跑到最后一行tail=0时并未将999压入循环队列
程序提前结束,想知道是哪里不对
队列的大小被定义为#define MAXN 1000,也就是说,队列的最大长度为1000。但是在你的代码中,并没有判断队列的长度是否超过了最大值,也就是说,你的队列长度是不受限制的,因此,在输入1 1 0 1050后,当队列中元素的数量超过了1000时,程序会崩溃
push函数中加一个:
if((tail+1)%MAXN == head){
// 队列已满,无法添加新元素
return;
}
不知道你这个问题是否已经解决, 如果还没有解决的话:经过分析,该问题可能存在以下几个方面的问题:
对于该问题,我们可以先检查输入参数是否正确,如果输入有问题,可以对输入进行格式化和纠错处理;如果输入正确,可以对程序的算法逻辑进行调试和检查,对程序的代码进行修正和规范化,同时加强对程序的测试和调试,以确保程序能够正常运行并得到正确的结果。
针对该问题,下面给出一个可能的解决方案:
n = input("请输入总台阶数n:")
if not n.isdigit() or int(n) <= 0:
print("输入有误,请输入一个正整数!")
n = input("请输入总台阶数n:")
a = input("请输入可爬台阶数(以逗号隔开):")
a_list = a.split(",")
for i in a_list:
if not i.isdigit() or int(i) <= 0:
print("输入有误,请输入一个正整数!")
a = input("请输入可爬台阶数(以逗号隔开):")
a_list = a.split(",")
m = input("请输入已损坏的台阶数m:")
if not m.isdigit() or int(m) <= 0:
print("输入有误,请输入一个正整数!")
m = input("请输入已损坏的台阶数m:")
b = input("请输入已损坏的台阶列表(以逗号隔开):")
b_list = b.split(",")
for i in b_list:
if not i.isdigit() or int(i) < 0 or int(i) >= int(n):
print("输入有误,请输入一个有效的台阶位置!")
b = input("请输入已损坏的台阶列表(以逗号隔开):")
b_list = b.split(",")
p = int(n) # 目的地为第p级台阶
q = [0] * (int(n) + 1) # 队列
visited = [False] * (int(n) + 1) # 标记数组
head = 0 # 队首
tail = 0 # 队尾
q[tail] = 0 # 入队
tail += 1
visited[0] = True # 标记为已访问
while head < tail:
cur = q[head] # 取出队首
head += 1
for i in range(len(a_list)):
next_step = cur + int(a_list[i]) # 计算下一步的位置
if next_step == p: # 到达目的地
print("F神可以到达第{}级台阶!".format(p))
break
if next_step > p: # 超出目的地
continue
if visited[next_step]: # 已经访问过
continue
if str(next_step) in b_list: # 损坏的台阶
continue
q[tail] = next_step # 入队
tail += 1
visited[next_step] = True # 标记为已访问
if cur == p: # 找到目的地后退出循环
break
if cur != p:
print("F神无法到达第{}级台阶!".format(p))
# 主程序
n = input("请输入总台阶数n:")
if not n.isdigit() or int(n) <= 0:
print("输入有误,请输入一个正整数!")
n = input("请输入总台阶数n:")
a = input("请输入可爬台阶数(以逗号隔开):")
a_list = a.split(",")
for i in a_list:
if not i.isdigit() or int(i) <= 0:
print("输入有误,请输入一个正整数!")
a = input("请输入可爬台阶数(以逗号隔开):")
a_list = a.split(",")
m = input("请输入已损坏的台阶数m:")
if not m.isdigit() or int(m) <= 0:
print("输入有误,请输入一个正整数!")
m = input("请输入已损坏的台阶数m:")
b = input("请输入已损坏的台阶列表(以逗号隔开):")
b_list = b.split(",")
for i in b_list:
if not i.isdigit() or int(i) < 0 or int(i) >= int(n):
print("输入有误,请输入一个有效的台阶位置!")
b = input("请输入已损坏的台阶列表(以逗号隔开):")
b_list = b.split(",")
p = int(n) # 目的地为第p级台阶
q = [0] * (int(n) + 1) # 队列
visited = [False] * (int(n) + 1) # 标记数组
head = 0 # 队首
tail = 0 # 队尾
q[tail] = 0 # 入队
tail += 1
visited[0] = True # 标记为已访问
while head < tail:
cur = q[head] # 取出队首
head += 1
for i in range(len(a_list)):
next_step = cur + int(a_list[i]) # 计算下一步的位置
if next_step == p: # 到达目的地
print("F神可以到达第{}级台阶!".format(p))
break
if next_step > p: # 超出目的地
continue
if visited[next_step]: # 已经访问过
continue
if str(next_step) in b_list: # 损坏的台阶
continue
q[tail] = next_step # 入队
tail += 1
visited[next_step] = True # 标记为已访问
if cur == p: # 找到目的地后退出循环
break
if cur != p:
print("F神无法到达第{}级台阶!".format(p))
# 主程序
# (同上,略)
# 模拟input()输入,进行测试
import io
input_data = '10\n2,3,5\n2\n3,5\n7\n'
input_data = io.StringIO(input_data).readline
print("测试用例1:总台阶数为10,可爬台阶数为2、3和5,共有2个已损坏的台阶,测试目的地为第7级台阶。")
n = input("请输入总台阶数n:", strip)
a = input("请输入可爬台阶数(以逗号隔开):", strip)
m = input("请输入已损坏的台阶数m:", strip)
b = input("请输入已损坏的台阶列表(以逗号隔开):", strip)
p = int(n) # 目的地为第p级台阶
q = [0] * (int(n) + 1) # 队列
visited = [False] * (int(n) + 1) # 标记数组
head = 0 # 队首
tail = 0 # 队尾
q[tail] = 0 # 入队
tail += 1
visited[0] = True # 标记为已访问
while head < tail:
cur = q[head] # 取出队首
head += 1
for i in range(len(a_list)):
next_step = cur + int(a_list[i]) # 计算下一步的位置
if next_step == p: # 到达目的地
print("F神可以到达第{}级台阶!".format(p))
break
if next_step > p: # 超出目的地
continue
if visited[next_step]: # 已经访问过
continue
if str(next_step) in b_list: # 损坏的台阶
continue
q[tail] = next_step # 入队
tail += 1
visited[next_step] = True # 标记为已访问
if cur == p: # 找到目的地后退出循环
break
if cur != p:
print("F神无法到达第{}级台阶!".format(p))
# 输出日志,进行测试
import logging
logging.basicConfig(filename='queue_alg.log', level=logging.INFO)
logging.info('测试用例1:总台阶数为10,可爬台阶数为2、3和5,共有2个已损坏的台阶,测试目的地为第7级台阶。')
n = 10
a_list = [2, 3, 5]
m = 2
b_list = [3, 5]
p = n
q = [0] * (int(n) + 1)
visited = [False] * (int(n) + 1)
head = 0
tail = 0
q[tail] = 0
tail += 1
visited[0] = True
while head < tail:
cur = q[head]
head += 1
for i in range(len(a_list)):
next_step = cur + int(a_list[i])
if next_step == p:
logging.info("F神可以到达第{}级台阶!".format(p))
break
if next_step > p:
continue
if visited[next_step]:
continue
if str(next_step) in b_list:
continue
q[tail] = next_step
tail += 1
visited[next_step] = True
if cur == p:
break
if cur != p:
logging.info("F神无法到达第{}级台阶!".format(p))
参考资料: