• [topcoder]ActivateGame


    http://community.topcoder.com/stat?c=problem_statement&pm=10750&rd=14153

    http://apps.topcoder.com/wiki/display/tc/SRM+470

    因为是棋盘型,然后就想到棋盘型DP;觉得不行,就想到BFS/DFS(这时其实已经把这个看成一张图了)。发现,寻找下一个节点进来的时候,总是要全局考虑所有已经Activate的点,BFS/DFS未果。此时感觉有点像最小生成树的Prim算法,用贪心的,但不知如何证明。此时看了一下题解,发现果然可以规约成最小生成树。因为本质是把棋盘看成一棵树后,整个过程就是Prim的过程。Kruskal的复杂度是O(e*loge),适合求稀疏的图,Prim的复杂度是O(n*n),与边无关,适合求稠密的图。(注:Prim使用堆优化效率可更高。)

    Prim算法的讲解:http://www.nocow.cn/index.php/Prim%E7%AE%97%E6%B3%95

    参考答案的实现也是O(n*n)的,n为w*h。虽然实现方法和纯粹用邻接表表示的有不同(因为具体问题),但效率并无退化。

    我在实现错误的将四个方向的组合从(1,0)这样的搞成了(1,-1)。这表示用两个数组,然后循环遍历,也很简洁。其实里面的变量可以命名为row, col等。

    int[] r = new int[] {0, 1, 0, -1};
    int[] v = new int[] {1, 0, -1, 0};
    

    代码:

    import java.math.*;
    public class ActivateGame
    {
    	public int findMaxScore(String[] grid)
    	{
    		int h = grid.length;
    		int w = grid[0].length();
    		boolean[][] activated = new boolean[h][w];
    		activated[0][0] = true;
    		int[] r = new int[] {0, 1, 0, -1};
    		int[] v = new int[] {1, 0, -1, 0};
    		int sum = 0;
    		for (int cnt = 1; cnt < h*w; cnt++)
    		{
    			int max = 0;
    			int ar = 0;
    			int av = 0;
    			for (int i = 0; i < h; i++)
    			for (int j = 0; j < w; j++)
    			{
    				if (activated[i][j])
    				{
    					for (int x = 0; x < 4; x++)
    					{
    						if (isValid(i+r[x], j+v[x], h, w) && !activated[i+r[x]][j+v[x]])
    						{
    							int score = Math.abs(getScore(grid[i].charAt(j))-
    												getScore(grid[i+r[x]].charAt(j+v[x])));
    							if (score > max) 
    							{
    								max = score;
    								ar = i+r[x];
    								av = j+v[x];
    							}
    						}
    					}
    				}
    			}
    			sum += max;
    			activated[ar][av] = true;
    		}
    		return sum;
    	}	
    	private int getScore(char c)
    	{
    		if (c >= '0' && c <= '9')
    		{
    			return c - '0';
    		}
    		else if (c >= 'a' && c <= 'z')
    		{
    			return c - 'a' + 10;
    		}
    		else if (c >= 'A' && c <= 'Z')
    		{
    			return c - 'A' + 36;
    		}
    		return 0;
    	}	
    	private boolean isValid(int x, int y, int h, int w)
    	{
    		return (x >=0 && x< h && y>=0 && y < w);
    	}
    }
    

      

  • 相关阅读:
    mysql对字段分割内容查询
    vue相关报错
    java多线程面试题
    java的消息队列
    电子商务大数据平台实训系统业务数据仓库总结
    电子商务大数据平台实训用户行为数仓业务总结
    电子商务大数据平台实训第一阶段总结
    Java 并发基础常见面试题总结
    window 平台 安装MongoDB
    java知识汇总(第六天)
  • 原文地址:https://www.cnblogs.com/lautsie/p/3344106.html
Copyright © 2020-2023  润新知