uva 10549 Russian Dolls (DP)

本文深入探讨了信息技术领域的各个方面,包括前端开发、后端开发、移动开发、游戏开发、大数据开发等。文章详细介绍了各领域的核心技术、工具和最佳实践,旨在为读者提供全面的技术知识体系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem D : Russian Dolls

From:UVA, 10549

Problem A: Russian Dolls

Russian nesting dolls are brightly painted hollowwooden figures. The dolls in a set have roughly the same shape, typically humanoid, but different sizes.When the set is assembled, the biggest doll containsthe second-biggest doll, the second-biggest containsthe third-biggest, and so on.

We can approximate the shape of a doll as a cylinder of height h, diameter d, and wall thickness w. Such a doll would have ahollow of height h-2w and diameter d-2w.

Boris and Natasha each has a set of dolls. Thesets are nearly identical; each has the same numberof dolls, which look the same but differ in their dimensions.Last night Boris and Natasha were playing with their dolls andleft them in the living room. Their mother tidiedthem away, dumping them all in one box. Can youhelp Boris and Natasha separate their sets of dolls?

Standard Input will consist of several test cases. Thefirst line of each test case will contain n, thenumber of dolls in each set (1 < n <= 100). 2nlines follow; each gives the dimensions, h, d,w of a different doll (h,d >= 2w > 0). A line containing 0 follows the last test case.

For each test case, separate the dolls into two sets ofnesting dolls such that, within each set, the dolls fitwithin each other, standing straight up, as described above. The first n lines of output should give thedimensions of the dolls in one set, in decreasing order byheight. The next line should contain a single hyphen, "-".The next n lines should give the dimensionsof the dolls in the second set, also in decreasing order by height. There will always be asolution. If there are many solutions,any will do. Output an empty line betweentest cases.

Sample Input

3
100 100 3
97 97 3
94 94 3
91 91 3
88 88 3
85 85 3
5
100 100 1
97 97 3
98 98 1
96 96 1
94 94 1
92 92 1
90 90 1
88 88 1
86 86 1
84 84 1
0

Possible Output

100 100 3
94 94 3
88 88 3
-
97 97 3
91 91 3
85 85 3

100 100 1
98 98 1
96 96 1
94 94 1
92 92 1
-
97 97 3
90 90 1
88 88 1
86 86 1
84 84 1

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;

const int maxn = 101;
bool dp[2*maxn][2*maxn][maxn][maxn];
short vis[2*maxn][2*maxn][maxn][maxn] = {0};
stack<int> v1 , v2;
struct DOLL{
	int h , d , w;
	DOLL(int a = 0 , int b = 0,int c = 0){
		h = a , d = b , w = c;
	}
}Doll[2*maxn];
int n;
short v;

bool cmp(DOLL d1 , DOLL d2){
	if(d1.h-2*d1.w == d2.h-2*d2.w){
		return d1.d-2*d1.w < d2.d-2*d2.w;
	}
	return d1.h-2*d1.w < d2.h-2*d2.w;
}

void readcase(){
	int h , d , w;
	for(int i = 1;i <= 2*n;i++){
		scanf("%d%d%d" , &h , &d , &w);
		Doll[i] = DOLL(h , d , w);
	}
}

bool check(int a , int b){
	if(Doll[a].d-2*Doll[a].w >= Doll[b].d && Doll[a].h-2*Doll[a].w >= Doll[b].h){
		return true;
	}
	//cout << a << "::::" << b<<"=" << Doll[a].h << " " << Doll[b].h << endl;
	return false;
}

bool DP(int k , int l , int r){
	//cout << k <<":" << l << " " << r << endl;
	if(k >= 2*n+1){
		//cout << v1.size() << v2.size() << endl;
		if(v1.size() == v2.size()){
			return true;
		}
		return false;
	}
	//cout << k <<":" << l << " " << r << endl;
	if(vis[l][r][v1.size()][v2.size()] == v) return dp[l][r][v1.size()][v2.size()];
	if(l == 0 || check(k , v1.top())){
		v1.push(k);
		if(DP(k+1 , k , r )){
			return dp[l][r][v1.size()-1][v2.size()] = true;
		}
		v1.pop();
	}
	if(r == 0 || check(k , v2.top())){
		v2.push(k);
		if(DP(k+1 , l , k )){
			return dp[l][r][v1.size()][v2.size()-1] = true;
		}
		v2.pop();
	}
	vis[l][r][v1.size()][v2.size()] = v;
	return dp[l][r][v1.size()][v2.size()] = false;
}

void computing(){
	sort(Doll+1 , Doll+2*n+1 , cmp);
	DP(1 , 0 , 0);
	while(!v2.empty()){
		int t = v2.top();
		v2.pop();
		printf("%d %d %d\n" , Doll[t].h , Doll[t].d , Doll[t].w);
	}
	printf("-\n");
	while(!v1.empty()){
		int t = v1.top();
		v1.pop();
		printf("%d %d %d\n" , Doll[t].h , Doll[t].d , Doll[t].w);
	}
}

int main(){
	//freopen("in" , "r" , stdin);
	v = 1;
	while(scanf("%d" , &n) == 1 && n){
		if(v != 1){
			printf("\n");
		}
		readcase();
		computing();
		v++;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值