Mobile Computing, ACM/ICPC Tokyo 2005, UVa1354 又长又暴力运行又慢的代码

题意:给一堆石头和长度为1的木棍,木棍端点可以挂石头或木棍,组成天平树。求不超过给定长度的最长天平。
解决:暴力枚举:每次在现有的石块/天平节点中任取两个,组成新的天平节点,直到取光;算出这颗天平树的平衡条件,得到天平长度。

代码:
//Mobile Computing
//My solution. Yhq
#include<iostream>
#include<cstring>
#include<iomanip>
#include<vector>
#include<queue>
using namespace std;
struct node;
void reset();
void dfs(int);
void calculate();
void print_tree(node);
double maxw;
double inf=1, sup=-1;
double width;
int num;
double stone[10];
bool vis[10];
vector<node*> nodes;
int main() {
	//freopen("MC.txt","w",stdout);
	int test;
	cin>>test;
	while (test--) {
		reset();
		cin>>width>>num;
		for (int i=1; i<=num; ++i) cin>>stone[i];
		dfs(0);
		if (maxw<0) cout<<maxw<<endl;
		else cout<<setiosflags(ios::fixed)<<setprecision(10)<<maxw<<endl;
	}
	return 0;
}
struct node{
	double lw, rw, ll, rl, pos; //left weight; right weight; left length; right length; position.
	node *left, *right;
	node(): lw(0), rw(0), ll(0), rl(0), pos(0), left(NULL), right(NULL) {}
};
void reset() {
	memset(vis,false,sizeof(vis));
	memset(stone,0,sizeof(stone));
	nodes.clear();
	maxw=-1;
}
void calculate(node root) {
	//print_tree(root);
	root.ll=root.rw/(root.rw+root.lw);
	root.rl=root.lw/(root.rw+root.lw);
	if (root.pos-root.ll < inf) inf=root.pos-root.ll;
	if (root.pos+root.rl > sup) sup=root.pos+root.rl;
	if (root.left) {
		root.left->pos=root.pos-root.ll;
		calculate(*(root.left));
	}
	if (root.right) {
		root.right->pos=root.pos+root.rl;
		calculate(*(root.right));
	}
}
void dfs (int depth) {
	if (depth==num-1) {
		nodes[0]->pos=0;
		inf=1, sup=-1;
		calculate(*nodes[0]);
		if (sup-inf<width && sup-inf>maxw) maxw=sup-inf;
		return;
	}
	for (int i=1; i<=num+5; ++i) {
		if (i<=num && !vis[i]) {
			vis[i]=true;
			int stone1=stone[i];
			for (int j=1; j<=num+5; ++j) {
				if (j<=num && !vis[j]) {
					vis[j]=true;
					int stone2=stone[j];
					node* newnode=new node;
					newnode->lw=stone1;
					newnode->rw=stone2;
					nodes.push_back(newnode);
					dfs(depth+1);
					nodes.pop_back();
					delete newnode;
					vis[j]=false;
				}
				else if (j>num && j-num<=nodes.size()) {
					vector<node*> tempvec=nodes;
					node *ptr=nodes[j-num-1];
					nodes.erase(nodes.begin()+j-num-1);
					node* newnode=new node;
					newnode->lw=stone1;
					newnode->rw=ptr->lw+ptr->rw;
					newnode->right=ptr;
					nodes.push_back(newnode);
					dfs(depth+1);
					delete newnode;
					nodes=tempvec;
				}
			}
			vis[i]=false;
		}
		else if (i>num && i-num<=nodes.size()) {
			vector<node*> tempvec=nodes;
			node *ptr1=nodes[i-num-1];
			nodes.erase(nodes.begin()+i-num-1);
			for (int j=1; j<=num+5; ++j) {
				if (j<=num && !vis[j]) {
					int stone2=stone[j];
					vis[j]=true;
					node* newnode = new node;
					newnode->lw=ptr1->lw+ptr1->rw;
					newnode->rw=stone2;
					newnode->left=ptr1;
					nodes.push_back(newnode);
					dfs(depth+1);
					nodes.pop_back();
					delete newnode;
					vis[j]=false;
				}
				else if (j>num && j-num<=nodes.size()) {
					node* ptr2=nodes[j-num-1];
					vector<node*> tempvec2=nodes;
					nodes.erase(nodes.begin()+j-num-1);
					node* newnode = new node;
					newnode->lw = ptr1->lw+ptr1->rw;
					newnode->rw = ptr2->lw+ptr2->rw;
					newnode->left = ptr1;
					newnode->right = ptr2;
					nodes.push_back(newnode);
					dfs(depth+1);
					delete newnode;
					nodes=tempvec2;
				}
			}
			nodes=tempvec;
		}
	} 
}
//debug
void print_tree(node root) {
	queue<node> que;
	que.push(root);
	cout<<"BFS Tree: "<<endl;
	while (!que.empty()) {
		node tmp=que.front();
		que.pop();
		cout<<"lw: "<<tmp.lw<<" "<<"rw:"<<tmp.rw<<endl;
		if (tmp.left) que.push(*(tmp.left));
		if (tmp.right) que.push(*(tmp.right));
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值