zoukankan      html  css  js  c++  java
  • uva 10051 Tower of Cubes(DAG最长路)

    题目连接:10051 - Tower of Cubes


    题目大意:有n个正方体,从序号1~n, 对应的每个立方体的6个面分别有它的颜色(用数字给出),现在想要将立方体堆成塔,并且上面的立方体的序号要小于下面立方体的序号,相邻的面颜色必须相同。输出最高值和路径。


    解题思路:因为立方体可以旋转,所以一个序号的立方体对应这6种不同的摆放方式,可以将问题理解成DAG最长路问题, 只是搜索范围是从i + 1开始到n。然后记录路径要开两个2维数组。


    路径不唯一,随便输出一条。


    #include <stdio.h>
    #include <string.h>
    const int N = 1005;
    const int M = 10;
    const char sign[M][10]= {"front", "back", "left", "right", "top", "bottom"};
    
    struct state {
        int in;
        int out;
    }tmp[N][M];
    int n, x[N][M], y[N][M], dp[N][M];
    
    void Init() {
        memset(tmp, 0, sizeof(tmp));
        memset(dp, 0, sizeof(dp));
        memset(x, 0, sizeof(x));
        memset(y, 0, sizeof(y));
    }
    
    void write(int k, int a, int b, int d) {
        tmp[d][k].in = a;
        tmp[d][k].out = b;
    }
    
    void read() {
        int a, b;
        for (int i = 1; i <= n; i++) {
    	for (int j = 0; j < 3; j++) {
    	    scanf("%d%d", &a, &b);
    	    write(j * 2, a, b, i);
    	    write(j * 2 + 1, b, a, i);
    	}
        }
    }
    
    int search(int d, int k) {
        if (dp[d][k])	return dp[d][k];
    
        for (int i = d + 1; i <= n; i++) {
    	for (int j = 0; j < 6; j++) {
    	    if (tmp[i][j].in == tmp[d][k].out) {
    		int a = search(i, j);
    		if (a > dp[d][k]) {
    		    dp[d][k] = a;
    		    x[d][k] = i, y[d][k] = j;
    		}
    	    }
    	}
        }
        return ++dp[d][k];
    }
    
    void solve() {
        int Max = 0, idx, idy, a;
        for (int i = 1; i <= n; i++) {
    	
    	if (Max + i >= n)   break;
    
    	for (int j = 0; j < 6; j++) {
    	    a = search(i, j);
    	    if (a > Max) {
    		Max = a;
    		idx = i, idy = j;
    	    }
    	}
        }
        printf("%d
    ", Max);
    
        for (int i = 0; i < Max; i++) {
    	printf("%d %s
    ", idx, sign[idy]);
    	a = idx;
    	idx = x[idx][idy];
    	idy = y[a][idy];
        }
    
        /*
        printf("%d
    ", dp[1][5]);
        idx = 1; idy = 5;
        for (int i = 0; idx; i++) {
    	printf("%d %s
    ", idx, sign[idy]);
    	a = idx;
    	idx = x[idx][idy];
    	idy = y[a][idy];
        }
        */
    }
    
    int main() {
        int cas = 0;
        while (scanf("%d", &n), n) {
    	Init();
    
    	read();
    
    	if (cas)    printf("
    ");
    
    	printf("Case #%d
    ", ++cas);
    
    	solve();
        }
        return 0;
    }
    


  • 相关阅读:
    有关远程设置的问题
    QT使用tableWidget显示双排列表 而且选中用红框圈出来
    一个程序猿的跨洋找工作分享
    linux块设备的IO调度算法和回写机制
    基于servlet实现一个web框架
    Java中的条件编译(转)
    Android NDK 使用第三方静态库(转)
    Android 使用动态库或静态库来编译生成动态库(转)
    Android应用运行过程(转)
    android NDK编译(导入).a文件和编译多个so文件(转)
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3313176.html
Copyright © 2011-2022 走看看