提升coding能力------搜索专题(5)-----poj 1480

pku 1480 Optimal Programs
题目地址:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1480

题目大意:

给你  x1 , x2 ,x3 ,x4,...xn

         y1 ,y2 ,y3 ,y4,...yn

问是否存在一组运算顺序,使得f(xi) = =yi (  1 <=i <= n ), 如果存在的话要输出运算次数最少的一组运算顺序,而且字典序要最小。

 

题意分析:

BFS + 大模拟,具体分析待填。

 

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<cstdlib>
#include<cmath>
using namespace std;
int x[20],y[20];
stack< int >stk1[11], stk2[11];
char name[5][4]={"ADD", "DIV","DUP","MUL","SUB"};
int path[20];
int cnt = 0;
int n;

int ADD(stack<int>& s1, stack<int>& s2)
{
    if(s1.size()<2)
        return 0;

    int opt1,opt2;

    opt1 = s1.top();
    s1.pop();

    opt2 = s1.top();
    s1.pop();

    if(abs(opt1 + opt2) > 30000)
    {
        s1.push(opt2);
        s1.push(opt1);

        return 0;
    }

    s1.push(opt1 + opt2);
    s2.push(opt1);
    s2.push(opt2);

    return 1;
}
int SUB(stack<int>& s1, stack<int>& s2)
{
    if(s1.size() < 2)
        return 0;

    int opt1,opt2;

    opt1 = s1.top();
    s1.pop();
    opt2 = s1.top();
    s1.pop();

    if(abs(opt2 - opt1) > 30000)
    {
        s1.push(opt2);
        s1.push(opt1);

        return 0;
    }

    s1.push(opt2 - opt1);
    s2.push(opt1);
    s2.push(opt2);

    return 1;
}
int MUL(stack<int>& s1, stack<int>& s2)
{

    if(s1.size() < 2)

        return 0;

    int opt1 ,opt2;

    opt1 = s1.top();
    s1.pop();

    opt2 = s1.top();
    s1.pop();

    if(abs(opt1*opt2) > 30000)
    {
        s1.push(opt2);
        s1.push(opt1);

        return 0;
    }

    s1.push(opt1*opt2);

    s2.push(opt1);
    s2.push(opt2);

    return 1;
}
int DIV(stack<int>& s1, stack<int>& s2)
{
    if(s1.size() <2 ||s1.top() == 0)
        return 0;

    int opt1 ,opt2;

    opt1 = s1.top();
    s1.pop();

    opt2 = s1.top();
    s1.pop();

    if(abs(opt2/opt1) > 30000)
    {
        s1.push(opt2);
        s1.push(opt1);

        return 0;

    }

    s1.push(opt2/opt1);

    s2.push(opt1);
    s2.push(opt2);

    return 1;
}
int DUP(stack<int>& s1, stack<int>& s2)
{
    if(s1.size()< 1 )
        return 0;

    s1.push(s1.top());

    return 1;
}
void rewind(int i ,int j)
{
    if(i != 2)
    {

            stk1[j].pop();
            stk1[j].push(stk2[j].top()),stk2[j].pop();
            stk1[j].push(stk2[j].top()),stk2[j].pop();
            return ;

    }

    stk1[j].pop();

    return;

}
int judge()
{
    for(int i = 0 ;i < n; i++)
    {
        if(stk1[i].size() != 1||stk1[i].top() != y[i])
            return 0;
    }

    return 1;

}
int DFS(int deep ,int h)
{

    if(deep > h)
        return 0;

    if(judge())
        return 1;



    for(int i = 0 ;i < 5 ;i++)
    {

        int j;
        switch(i)
        {
            case 0:
                   for(j = 0 ;j < n; j++)
                      if(!ADD(stk1[j],stk2[j]))
                          break;

                    break;
            case 1:
                    for(j= 0 ;j < n; j++)
                      if(!DIV(stk1[j],stk2[j]))
                          break;
                    break;
            case 2:
                    for(j= 0 ;j < n; j++)
                      if(!DUP(stk1[j],stk2[j]))
                          break;
                    break;
            case 3:
                    for(j= 0 ;j < n; j++)
                        if(!MUL(stk1[j],stk2[j]))
                             break;
                    break;
            case 4:
                     for(j= 0 ;j < n; j++)
                       if(!SUB(stk1[j],stk2[j]))
                           break;
                    break;



         }




         if(j < n)
         {
            for(int k = (-- j ); k >=0 ; k--)
               rewind(i , k);

               continue;
         }


        path[ cnt++ ] = i;
        if(DFS(deep + 1, h))
           return 1;

        for(int k = (-- j ); k >=0 ; k--)
            rewind(i , k);

        cnt--;



    }


    return 0;
}
int main()
{
    int num = 0;
    while(cin>> n)
    {
        num++;
        if(n == 0)
            break;

        for(int i = 0 ;i < 11 ; i++)
        {
           while(!stk1[i].empty())
             stk1[i].pop();

            while(!stk2[i].empty())
                stk2[i].pop();
        }

        cnt = 0;
        for(int i = 0 ;i < n;i++ )
        {
            cin >> x[i];
            stk1[i].push(x[i]);

        }
        int flag = 1;
        for(int i= 0 ;i < n;i++)
        {
            cin >> y[i];

            if(y[i] != x[i])
                flag = 0;
        }




        printf("Program %d\n", num);
        if(flag)
        {
            cout <<"Empty sequence\n" << endl;
            continue;
        }

        int h;
        for(h = 1 ;h <= 10 ; h++ )
        {
            if(DFS(0,h))
                break;

        }

        if(h == 11)
            cout <<"Impossible\n" << endl;

        else
        {

            for(int i = 0 ;i < cnt ;i++)
                cout << name[path[i]] << " ";

            cout << "\n" << endl;
        }





    }

    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值