ZOJ 1011 NTA

刚开始用c做, 各种链表队列,分配内存……然后就懵逼了,而且是用的从上往下遍历树的,做的有些麻烦,加之这个题的测试数据中存在非法数据,就是说如果k = 3, 本应该是只有a, b, c, 但是测试数据中存在超出k的转换元素,例如存在d….这对于限制严格,一切由程序员控制的c语言来说,就毫无疑问的段错误了,数组越界没得跑,毕竟我是malloc的内存,没有多余的地方。而且对于这种非法转换元素应该如何处理也不知道,简直坑……

说一下最后的解决吧,还是用了不熟的C++, 在借用了网上他人的思路自己实现了一遍,用了不一样的数据结构,然后倒在了STL身上(所以说不熟啊…),最终使用了较为简单的数组AC了,不过我一定会搞明白错误原因的!

注释掉的代码就是原本用的模板…

#include <iostream>
#include <vector>
#include <bitset>
#include <string>
#include <memory.h>

using namespace std;

#define SIG_MAX 15
#define TRAN_MAX 10
#define L_MAX 10

typedef struct 
{
    int l;
    int r;
}tranElement;

vector<tranElement> tranTable[SIG_MAX][TRAN_MAX];

int main(int argc, char* argv[])
{
    int n, m, k;
    int ntaNumber = 0;
    // vector< bitset<SIG_MAX> > isValid(4096);
    int isValid[4096][15];
    int tree[4096];

    while(true)
    {
        int a, b;
        int i, j;

        cin >> n >> m >> k;
        if(n==0&&m==0&&k==0)
            break;
        if(ntaNumber)
            cout << endl;
        ntaNumber++;
        cout << "NTA" << ntaNumber << ":" << endl;

        for(i = 0;i < SIG_MAX;i++)
            for(j = 0;j < TRAN_MAX;j++)
            {
                tranTable[i][j].clear();
            }

        for(i = 0;i < n;i++)
            for(j = 0;j < k;j++)
            {
                while(1)
                {
                    tranElement now;
                    cin >> now.l >> now.r;
                    tranTable[i][j].push_back(now);
                    if(cin.get() == '\n')
                        break;
                }
            }




        int L;
        while(true)
        {

            cin >> L;
            if(L==-1)
                break;
            int height = L+1;
            int number = (1<<height)-1;
            int cnt = 1;
            memset(tree, -1, sizeof(tree));
            memset(isValid, 0, sizeof(isValid));

            // vector<int> tree((1<<(L+2))-1, -1);

            // for(i = 1;i <= ((1<<(L+2))-1);i++)
            //  isValid[i].reset();



            for(i = 1;i <= number;i++)
            {
                char c;
                cin >> c;
                if(c == '*')
                    tree[i] = -1;
                else
                    tree[i] = c - 'a';
            }


            // judge
            int pos;
            for(pos = ((1 << (L + 2)) - 1);pos > 0;pos--)
            {
                int tranEle = tree[pos];
                if(tranEle == -1)
                {
                    int sig;
                    for(sig = 0;sig < n;sig++)
                        if(sig >= n-m)
                            isValid[pos][sig] = 1;
                }
                else
                {
                    int sig;
                    for(sig = 0;sig < n;sig++)
                        if(tranTable[sig][tranEle].size())
                        {
                            vector<tranElement>::iterator iter = tranTable[sig][tranEle].begin();
                            while(iter != tranTable[sig][tranEle].end())
                            {
                                if(isValid[pos*2][iter->l] && isValid[pos*2+1][iter->r])
                                {
                                    isValid[pos][sig] = 1;
                                    break;
                                }
                                iter++;
                            }
                        }
                }
            }

            if(isValid[1][0])
                cout << "Valid" << endl;
            else
                cout << "Invalid" << endl; 
        }
    }
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值