浙大ZOJ 1011 NTA问题解决

注:在输入数据的获取与处理上花了不少时间,因为每行的输入数据的个数不再确定,所以需要先读取一行,然后从该行字符串中解析出我们需要的数据。

一、工程代码及算法设计注释

--------------------------------------------------nta.h----------------------------------------------

#ifndef JLU_CCST_NTA_H
#define JLU_CCST_NTA_H
#include <vector>
struct SignalPair{
	int x,y;
	SignalPair(int xx=0,int yy=0):x(xx),y(yy) {} ;
};

struct TreeNode{
	char transmiter;
	TreeNode* left;
	TreeNode* right;
	TreeNode(char trans='a',TreeNode* l=NULL,TreeNode* r=NULL):transmiter(trans),left(l),right(r) {} ;
};

extern bool isNTATreeValid(const std::vector<std::vector<SignalPair> >& transitionTable,int signal,int n,int m,int k,TreeNode* root);
extern void testIsNTATreeValid();

#endif//JLU_CCST_NTA_H

-------------------------------------------------- nta.cpp ----------------------------------------------

/**
题目来源:浙大ACM在线测试——ZOJ,题目编号1011,题名"NTA"
URL:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1011
Author:hellogdc<gdcjlu@163.com>
Finish Time:2014.01.09
*/

/**
算法设计:
利用递归思想来解决该问题,即判断一棵树是否“shakable”,可转化为判断这颗树根节点的左子树和右子树
是否同时“shakable”。如果可以,则说明该树“shakable”;否则,则不可以。

关于树的表示:
用最传统的二叉树来表示,每个节点由3个元素组成:左儿子、右儿子和信号发射器。
*/
#include <iostream>
#include <vector>
#include "nta.h"
using namespace std;

/**
给定NTA,判断一棵树是否“shakable”。如是,则返回true;否则,返回false。
transitionTable:信号转发表,此处是用一个数组来模拟矩阵的,行坐标为信号值(从0开始),列坐标为信号发射器值(从a开始)。
sinal:该树根节点收到的信号(从0开始)。
n:NTA信号个数
m:NTA信号"acceptable"的个数
k:NTA信号发射器个数
root:要判断的树的根节点,另外这棵树的每个非叶子节点必须有2个子节点。
*/
bool isNTATreeValid(const vector<vector<SignalPair> >& transitionTable,int signal,int n,int m,int k,TreeNode* root){
	if( (root->left==NULL&&root->right!=NULL)||
		(root->left!=NULL&&root->right==NULL) )
		return false;
	int acceptMin=n-m;

	vector<SignalPair> pairs=transitionTable.at(signal*k+root->transmiter-'a');

	//处理叶子节点
	if(root->left==NULL&&root->right==NULL){
		//查表
		for(vector<SignalPair>::iterator it=pairs.begin();it!=pairs.end();it++){
			if(it->x>=acceptMin&&it->y>=acceptMin)
				return true;
		}
		return false;
	}

	//处理非叶子节点
	for(vector<SignalPair>::iterator it=pairs.begin();it!=pairs.end();it++){
		if( isNTATreeValid(transitionTable,it->x,n,m,k,root->left) ){
			if( isNTATreeValid(transitionTable,it->y,n,m,k,root->right) ){
				return true;
			}
		}
	}
	return false;
}

static void freeTree(TreeNode* root){
	if(root==NULL)
		return;
	freeTree(root->left);
	freeTree(root->right);
	delete root;
}

/Test Case/

void testIsNTATreeValid(){
	vector<vector<SignalPair> > transitionTable;
	int n,m,k;
	
	transitionTable.clear();
	n=4;m=2;k=3;
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(1,2));
		transitionTable.push_back(pairs);
	}
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(2,1));
		transitionTable.push_back(pairs);
	}
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(1,0));
		transitionTable.push_back(pairs);
	}
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(2,2));
		transitionTable.push_back(pairs);
	}
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(0,2));
		pairs.push_back(SignalPair(1,0));
		transitionTable.push_back(pairs);
	}
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(3,2));
		transitionTable.push_back(pairs);
	}
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(2,2));
		transitionTable.push_back(pairs);
	}
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(2,3));
		transitionTable.push_back(pairs);
	}
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(1,2));
		transitionTable.push_back(pairs);
	}
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(1,2));
		transitionTable.push_back(pairs);
	}
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(2,1));
		transitionTable.push_back(pairs);
	}
	{
		vector<SignalPair> pairs;
		pairs.push_back(SignalPair(3,2));
		transitionTable.push_back(pairs);
	}
	TreeNode* root=new TreeNode('a');
	root->left=new TreeNode('b');
	root->right=new TreeNode('c');

	root->left->left=new TreeNode('a');
	root->left->right=new TreeNode('b');
	root->right->left=new TreeNode('c');
	root->right->right=new TreeNode('b');

	root->left->left->left=new TreeNode('b');
	root->left->left->right=new TreeNode('a');
	root->left->right->left=new TreeNode('b');
	root->left->right->right=new TreeNode('a');
	root->right->left->left=new TreeNode('c');
	root->right->left->right=new TreeNode('a');

	TreeNode* root2=new TreeNode('b');
	root2->left=new TreeNode('a');
	root2->right=new TreeNode('b');
	root2->left->left=new TreeNode('b');
	root2->left->right=new TreeNode('c');

	bool flag=false;
	flag=isNTATreeValid(transitionTable,0,n,m,k,root);
	if(flag)
		cout<<"Valid"<<endl;
	else
		cout<<"Invalid"<<endl;
	flag=isNTATreeValid(transitionTable,0,n,m,k,root2);
	if(flag)
		cout<<"Valid"<<endl;
	else
		cout<<"Invalid"<<endl;

	freeTree(root);
	freeTree(root2);
}

--------------------------------------------------main.cpp----------------------------------------------

#if 1

#include "nta.h"
int main(){
	testIsNTATreeValid();

	return 0;
}

#endif


二、 提交并被ZOJ成功接受的代码——算法核心代码

--------------------------------------------------submit_main.cpp----------------------------------------------

#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <cstdlib>
using namespace std;
struct SignalPair{
	int x,y;
	SignalPair(int xx=0,int yy=0):x(xx),y(yy) {} ;
};

struct TreeNode{
	char transmiter;
	TreeNode* left;
	TreeNode* right;
	TreeNode(char trans='a',TreeNode* l=NULL,TreeNode* r=NULL):transmiter(trans),left(l),right(r) {} ;
};
bool IsNTATreeValid(const vector<vector<SignalPair> >& transitionTable,int signal,int n,int m,int k,TreeNode* root){
	if( (root->left==NULL&&root->right!=NULL)||
		(root->left!=NULL&&root->right==NULL) )
		return false;
	int acceptMin=n-m;
	vector<SignalPair> pairs=transitionTable.at(signal*k+root->transmiter-'a');
	if(root->left==NULL&&root->right==NULL){
		for(vector<SignalPair>::iterator it=pairs.begin();it!=pairs.end();it++){
			if(it->x>=acceptMin&&it->y>=acceptMin)
				return true;
		}
		return false;
	}
	for(vector<SignalPair>::iterator it=pairs.begin();it!=pairs.end();it++){
		if( IsNTATreeValid(transitionTable,it->x,n,m,k,root->left) ){
			if( IsNTATreeValid(transitionTable,it->y,n,m,k,root->right) ){
				return true;
			}
		}
	}
	return false;
}

static void freeTree(TreeNode* root){
	if(root==NULL)
		return;
	freeTree(root->left);
	freeTree(root->right);
	delete root;
}

int main(){
	vector<vector<vector<SignalPair> > > transitionTables;
	vector<vector<TreeNode*> > trees;
	vector<int> nS;
	vector<int> mS;
	vector<int> kS;
	int n,m,k,level;
	//because the max number of signal is 15, 15*15=225,225*2+224<800, so it's enough to store the input
	char inBuf[800];
	string line;
	while(getline(cin,line)){
		int start=0;
		int end=line.find(" ",start);
		string value=line.substr(start,end-start);
		n=atoi(value.c_str());
		start=end+1;
		end=line.find(" ",start);
		value=line.substr(start,end-start);
		m=atoi(value.c_str());
		start=end+1;
		end=line.find(" ",start);
		if(end==string::npos)
			end=line.length();
		value=line.substr(start,end-start);
		k=atoi(value.c_str());

		if(n==0&&m==0&&k==0)
			break;
		nS.push_back(n);
		mS.push_back(m);
		kS.push_back(k);

		int tableSize=n*k;
		vector<vector<SignalPair> > transitionTable(tableSize);
		for(int i=0;i<tableSize;i++){
			vector<SignalPair> paris;
			//line=inBuf;
			getline(cin,line);
			int j=0;
			int start=0,end=0;
			while(start<line.length()){
				SignalPair pair;
				string value;
				end=line.find(" ",start);
				value=line.substr(start,end-start);
				pair.x=atoi(value.c_str());
				start=end+1;
				end=line.find(" ",start);
				if(end==string::npos)
					end=line.length();
				value=line.substr(start,end-start);
				pair.y=atoi(value.c_str());
				start=end+1;
				paris.push_back(pair);
			}
			transitionTable[i]=paris;
		}
		transitionTables.push_back(transitionTable);

		vector<TreeNode *> roots;
		while(getline(cin,line)){
			int start=0;
			int end=line.find(" ",start);
			if(end==string::npos)
				end=line.length();
			string value=line.substr(start,end-start);
			level=atoi(value.c_str());
			if(level==-1)
				break;
			vector<TreeNode*> nodes((int)pow(2.0,level+1)-1);
			int no=0;
			for(int i=0;i<=level;i++){
				getline(cin,line);
				for(int j=0;j<line.length();j+=2){
					TreeNode* node=new TreeNode(line[j]);
					nodes[no++]=node;
				}
			}
			int nNonLeaf=(int)pow(2.0,level)-1;
			for(int i=0;i<nNonLeaf;i++){
				if(nodes[i]->transmiter=='*'){
					delete nodes[i];
					continue;
				}
				int sonI=2*i+1;
				if(nodes[sonI]->transmiter!='*')
					nodes[i]->left=nodes[sonI];
				else{
					nodes[i]->left=NULL;
					delete nodes[sonI];
				}
				if(nodes[sonI+1]->transmiter!='*')
					nodes[i]->right=nodes[sonI+1];
				else{
					nodes[i]->right=NULL;
					delete nodes[sonI+1];
				}
			}
			roots.push_back(nodes[0]);
		}
		trees.push_back(roots);
	}
	for(int i=0;i<trees.size();i++){
		bool flag=false;
		if(i!=0)
			cout<<endl;
		cout<<"NTA"<<(i+1)<<":"<<endl;
		for(vector<TreeNode*>::iterator it=trees[i].begin();it!=trees[i].end();it++){
			flag=IsNTATreeValid(transitionTables[i],0,nS[i],mS[i],kS[i],*it);
			if(flag)
				cout<<"Valid"<<endl;
			else
				cout<<"Invalid"<<endl;
		}
	}
	for(int i=0;i<trees.size();i++){
		for(vector<TreeNode*>::iterator it=trees[i].begin();it!=trees[i].end();it++){
			freeTree(*it);
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值