华为杯编程比赛最后一题题目附上自己的解题代码

题目:

超哥来到一间密室,忽然一阵阴风把门关上了。魔法学校的门需要魔力才能打开,而超哥没有那间密室的魔力。超哥继续往密室深处走,发现一堆魔法瓶和一些古老的文字。上面写着:欲开启密室,需收集所有瓶中魔力。开启魔法瓶需严格按照顺序,否则将焚毁密室…
文字记载了一个 N×N 的0,1矩阵 GN×N ,还记录了任意两个魔法瓶之间的开启规则:
你可以从任意一个魔法瓶开始。
魔法瓶 j 能在紧随魔法瓶 i 之后被安全打开,当且仅当 Gi,j=1
魔法瓶 j 紧随魔法瓶 i 之后被打开,密室会被焚毁,当且仅当 Gi,j=0
文字最后写道,任意两个魔法瓶,都可以相邻。即: Gi,jGj,i=1(ij)
你能帮超哥找到一个开启所有魔法瓶方案吗?

输入

第一行一个整数 N ,魔法瓶的个数,接着 N 行,每行 N 个数,0或1。
i 行第 j 列为1,表示开启第 i 个魔法瓶后,下一个开启的魔法瓶可以是 j
保证矩阵 第 i 行第 j 列与 第 j 行第 i 列数值不同,第 i i 列为0。
N1000

输出

N 个数,空格隔开,表示打开魔法瓶编号顺序。

样例输入

2
0 0
1 0

样例输出

2 1
以下是我的代码,但是还不知道是否正确,贴出来和大家一起讨论讨论:

#include<iostream>
#include<stack>
using namespace std;

int main(){
	int n;
	cin>>n;
	stack<int> ways;
	int *bottles=new int[n*n];
	for(int i=0;i<n*n;i++){
		cin>>bottles[i];
	}
	int index=1;
	int count=1;
	while(count<n){
		if(bottles[index-1] == 0){
			int a=index/n;
			int b=index%n;
			if(b == 0){
				a--;
				b=n;
			}
			//如果是在每行的结尾且没有值为1的点
			if(b == n){
				//堆栈不为空的话,弹出头
				if(!ways.empty()){
				int ll=ways.top();
				ways.pop();
				int lll=ways.top();
				ways.pop();
				count--;
				index=n*(lll-1)+ll+1;
				}
				//堆栈为空,即代表前面全部没有符合的情况,则index只是加1.
				else{
					index++;
				}

			     }
          //不是行尾的话,index加1就可
			else {
				index++;
			}

		}
        //节点值为1的时候,把行,列值push进堆栈
		else{
			int a=index/n;
			int b=index%n;
			if(b == 0){
				a--;
				b=n;
			}
			ways.push(a+1);
			ways.push(b);
			count++;
			index=n*(b-1)+1;
		}

	}
	//整个表检查结束,把堆栈里面的数字放进数组
	int *result=new int[2*n-2];
	for(int j=2*n-3;j>=0;j--){
		int temp=ways.top();
		result[j]=temp;
		ways.pop();
	}  
	for(int k=0;k<2*n-2;k++){
		if(k == 0 || k == 2*n-3)
		 cout<<result[k]<<" ";
		else {
			if(k%2 == 1)
               cout<<result[k]<<" ";
		}
	} 

	return 0;
}

每次参加比赛都会紧张得脑子短路,当时也没能做出来。。不知道对不对

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值