题目不说了,其实还是很简单的,只需要再去处理一下如何表示顶点就可以了。
但这个里面有一个值得探讨的小细节,就是如果输入的长方体有相同的边,那么在顶点里面不就重复了吗?
不过好在在这道题目中,有相同的点并没有什么影响,因为这两个顶点之间根本不存在边
还有一点就是,汝佳的代码里面没有建图,可以是可以,但是那样的话,对编写代码的要求又提高了一些,但是时间效率并没有差很多
下面附上AC代码:
//这题思路很明确,对每一个长方体都都搞出三种不同的形态(最多),然后每一种形态代表一个顶点,最多有90个这样的顶点(同一种形态的不可能使用两次) //然后对这些顶点构造有向图 //最后就是求从每一个节点出发的可以构建的最大的高度 //需要仔细思考的地方在于 //使用set来构造这样的集合,以防止出现同构的长方体 //其实同不同构无所谓 //忘了考虑需要严格大于!!!并不是面积大于 #include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; const int maxn = 100; struct node { int x,y,h; }Node[maxn]; int n; int G[maxn][maxn]; int vis[maxn]; int d[maxn]; void print_G() { for(int i = 0;i < 3 * n;i++) { for(int j = 0;j < 3 * n;j++) { printf("%d ",G[i][j]); } printf("\n"); } } bool creat_G() { memset(vis,0,sizeof(vis)); memset(G,0,sizeof(G)); scanf("%d",&n); if(!n) return false; for(int i = 0;i < n;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); Node[3 * i ].x = a; Node[3 * i ].y = b; Node[3 * i ].h = c; Node[3 * i + 1].x = a; Node[3 * i + 1].y = c; Node[3 * i + 1].h = b; Node[3 * i + 2].x = c; Node[3 * i + 2].y = b; Node[3 * i + 2].h = a; } for(int i = 0;i < 3 * n;i++) { for(int j = 0;j < 3 * n;j++) { //有向边代表可以放到那一块上 if((Node[i].x < Node[j].x && Node[i].y < Node[j].y )||(Node[i].x < Node[j].y && Node[i].y < Node[j].x )) { G[i][j] = 1; } } } //print_G(); return true; } int dp(int x) { if(vis[x]) return d[x]; vis[x] = 1; int ans = 0; for(int i = 0;i < 3 * n;i++) { if(G[x][i]) { ans = max(ans,dp(i)); } } ans = ans + Node[x].h; d[x] = ans; return d[x]; } int main() { #ifdef local freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif int kase = 0; while(creat_G()) { printf("Case %d: maximum height = ",++kase); int Max = 0; for(int i = 0;i < 3 * n;i++) { if(!vis[i]) { Max = max(dp(i),Max); } } printf("%d\n",Max); } return 0; }