魔法筒问题

题目描述:    

        给定从1到n编号的那个球,n个球掉入两个魔法筒内,每个魔法筒视为一个栈,即“先进后出”。魔法筒使得我们每次只能从桶的顶端拿走当前两个魔法桶中的所有球编号的最小球,或者将顶端的球放到另外一个魔法筒的顶端。问至少需要多小次才能将所有球从同种取出。

输入:

        第一行,三个正整数n, x, y。分别代表球的总数,第一个桶中的球数和第二个桶中的球数

        第二行,有x个数,代表第一桶中从低端到顶端的x个球

        第二行,有y个数,代表第二个桶中从低端到顶端的y个球

输出:答案

如: 输入:

                5 2 3

                3 4

                2 5 1

输出: 8

提示:从第二桶中取出1,然后将5放入桶1,取出2,再从桶1中取出5 、 4 、 3;

代码:

C++;

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,x,y;
    cin>>n>>x>>y;
    stack<int> stk1;
    stack<int> stk2;
    unordered_set<int> u1;
    unordered_set<int> u2;
    for(int i=0;i<x;i++){
        int num;
        cin >> num;
        u1.insert(num);
        stk1.push(num);
    }
    for(int i=0;i<y;i++){
        int num;
        cin >> num;
        u2.insert(num);
        stk2.push(num);
    }
    int count = 0;
    for(int i=0;i<=n;i++){
        if(u1.find(i)!=u1.end()){
            while(!stk1.empty() && stk1.top()!=i){
                int cur = stk1.top();            
                stk2.push(cur);
                u1.erase(cur);
                u2.insert(cur);
                stk1.pop();
                count++;
            }
            if(!stk1.empty()){
                stk1.pop();
                count++;
            }
        }else{
             while(!stk2.empty() && stk2.top()!=i){
                int cur = stk2.top();
                
                stk1.push(cur);
                u2.erase(cur);
                u1.insert(cur);
                stk2.pop();
                count++;
            }
            if(!stk2.empty()){
                stk2.pop();
                count++;
            }
        }
    }
    cout << count<<endl;
    return 0;
}

JAVA:

import java.util.*;

public class Main3 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] line1 = sc.nextLine().split(" ");
        int n = Integer.parseInt(line1[0]);
        int x = Integer.parseInt(line1[1]);
        int y = Integer.parseInt(line1[2]);

        Stack<Integer> stack1 = new Stack<>();
        Stack<Integer> stack2 = new Stack<>();

        // 存放第i球在那个栈
        int[] Pos = new int[n+1];

        String[] line2 = sc.nextLine().split(" ");
        for(int i=0; i<x; i++){
            stack1.push(Integer.valueOf(line2[i]));
            Pos[Integer.valueOf(line2[i])] = 1;
        }

        String[] line3 = sc.nextLine().split(" ");
        for(int i=0; i<y; i++){
            stack2.push(Integer.valueOf(line3[i]));
            Pos[Integer.valueOf(line3[i])] = 2;
        }
        int count = 0;
        for(int i=1; i<=n; i++){
        // 位置
            int pp = Pos[i];
            if(pp ==1 ){
                // 如果栈1不为空,且栈顶元素不等于i
                while (!stack1.empty() && stack1.peek()!=i){
                    int cur = stack1.pop();
                    stack2.push(cur);
                    Pos[cur] = 2;
                    count++;
                }
                if(!stack1.empty()){
                    int cur = stack1.pop();     // 取出i,并将Pos[i]置0
                    count++;
                }
            }else if(pp == 2){
                // 如果栈1不为空,且栈顶元素不等于i
                while (!stack2.empty() && stack2.peek()!=i){
                    int cur = stack2.pop();
                    stack1.push(cur);
                    Pos[cur] = 1;
                    count++;
                }
                if(!stack2.empty()){
                    int cur = stack2.pop();     // 取出i,并将Pos[i]置0
                    count++;
                }
            }else{// 此时已被取出

            }
        }
        System.out.println(count);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值