zoukankan      html  css  js  c++  java
  • UVA

    /*
    题目链接:
    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=747
    
    白书对此题的评价:
    本题有一定实际意义,而且需要注意细节,建议读者一试
    
    ----------------------------------------------------
    参考的题解:
    http://blog.csdn.net/crazysillynerd/article/details/43882593
    //这个博主的题目解释,可谓是相当详细。在看书上的中文题意以后,我其实是觉得有些细节没有明白。再上 uva 看英文原题时,仍然不太明白。最后是看到这个博主的解释,我才豁然开朗...
    
    */


    /*
      借鉴思路于:
      http://blog.csdn.net/u014800748/article/details/44866133
    */
    #include <iostream>
    #include <stack>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #define rep(i, j, n) for (int i = j; i < (n); i++)
    #define Clean(i, j) memset(i, j, sizeof(i))
    using namespace std;
    
    const int N = 64 + 5;
    char g[N][N];
    vector<int>code;
    int n;
    struct Node
    {
    	int color; //黑色或白色 
    	int dir; // 表示方向,不同的方向 (NW、NE、SW、SE)有不同的权重 
    }node[N * N];
    
    void encode(int r, int c, int w, int dir, int &id)
    { //(r, c)表示起点坐标,w表示宽度,dir表示编码后的方向,id表示结点编号(传引用使得,如果该区域确实可以用一个结点来表示,那么下次再标结点时,标号就从 id+1 开始) 
    	int ok = 1;
    	char ch = g[r][c];
    	rep(i, r, r + w)
    	rep(j, c, c + w)
    	if (g[i][j] != ch)
    	{
    		ok = 0; //表示这个区域里有不同颜色的情况,这个区域必须划分四等分 
    		break;
    	}
    	if (ok) //表示该区域同色,可作为一个结点处理 
    	{
    		node[id].color = (ch == '0' ? 0 : 1);
    		int x = dir, k = 1;
    		stack<int> s; // 利用栈来实现五进制向十进制的转换
    		while (x > 0)
    		{
    			s.push(x % 10);
    			x /= 10;
    		}
    		while ( !s.empty() )
    		{
    			node[id].dir += s.top() * k; s.pop();
    			k *= 5;
    		}
    		id++;
    	}
    	else //该区域有不同色,则分为四个区域,递归编码 
    	{
    		encode ( r, c, w / 2, dir * 10 + 1, id );
    		encode ( r, c + w / 2, w / 2, dir * 10 + 2, id );
    		encode ( r + w / 2, c, w / 2, dir * 10 + 3, id );
    		encode ( r + w / 2, c + w / 2, w / 2, dir * 10 + 4, id);
    	}
    }
    
    void draw (int r, int c, int w)
    {
    	rep(i, r, r + w) rep(j, c, c + w)
    	g[i][j] = '*';
    }
    void decode(vector<int> s)
    {
    	int size = (int)s.size();
    	rep(i, 0, size)
    	{
    		int x = s[i], k = 1;
    		node[i].color = 1;
    		while (x > 0) //解码路径,低位是靠近树根的路径
    		{
    			node[i].dir += ( x % 5 ) * k;
    			x /= 5, k *= 10;
    		}
    	}
    	
    	rep(i, 0, size)
    	{
    		int dir = node[i].dir;
    		int r = 0, c = 0, w = n;
    		while (dir > 0) //沿路径找区域
    		{
    			int x = dir % 10; //越是靠近各位的位,对应的是越靠近根节点的路径,从根出发,所以从个位开始 
    			w /= 2, dir /= 10; //注意此时的 w 已经减半了,所以后面累加到 r 或是 c 上时,不必再减半 
    			if (x == 2) c += w;
    			else if (x == 3) r += w;
    			else if (x == 4) c += w, r += w;
    		}
    		draw(r, c, w); 
    	}
    	
    	rep(i, 0, n) rep(j, 0, n)
    	if (g[i][j] != '*') g[i][j] = '.';
    	
    	rep(i, 0, n) puts(g[i]);
    }
    
    void solve()
    {
    	int kase = 0;
    	while ( scanf("%d", &n), n )
    	{
    		Clean(g, '');
    		Clean(node, 0);
    		if (kase) printf("
    ");
    		printf("Image %d
    ", ++kase);
    		
    		if (n > 0)
    		{
    			rep(i, 0, n) scanf("%s", g[i]);
    			int id = 1;
    			encode(0, 0, n, 0, id); //编码整张图
    			vector<int> ans;
    			rep(i, 1, id) if (node[i].color == 1) ans.push_back(node[i].dir); 
    			sort(ans.begin(), ans.end());
    			rep(i, 0, (int)ans.size())
    			{
    				printf("%d", ans[i]);
    				if ( (i + 1) % 12 == 0 || i == (int)ans.size() - 1) printf("
    ");
    				else printf(" ");
    			}
    			printf("Total number of black nodes = %d
    ", (int)ans.size());
    		}
    		else
    		{
    			code.clear();
    			n = -n;
    			int x;
    			while (scanf("%d", &x) && x != -1) code.push_back(x);
    			decode(code); //解码,画图 
    		}
    	}
    }
    int main()
    {
    	solve();
    	return 0;
    }
    
    /*
    查阅的其他资料:
    https://zhidao.baidu.com/question/578232457.html
    http://blog.csdn.net/xingjiarong/article/details/47282817
    */




  • 相关阅读:
    Could not transfer artifact org.apache.maven.plugins:maven-resources-plugin:pom:2.6 from/to central
    SpringMVC详解
    数据库连接池
    事务的隔离级别
    数据库四大特性
    Eclipse自动编码提示设置
    RequestDispatcher.forward转发与HttpServletResponse.sendRedirect重定向
    c#代码混淆
    java反射机制
    (转)redis是什么
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789347.html
Copyright © 2011-2022 走看看