codeforces #300 D. Weird Chess

一个人沉迷象棋了,感觉原来的象棋规则没意思,思考更牛逼的象棋规则,从而变象棋界大神。


棋盘是n*n的矩形,棋盘上有 X| .(点)|和O  那个是点,就一个英文标点的点。


也就是你在棋盘上若干个地方放上了棋子O, 能攻击到棋盘上被画上X的地方。


然后你定义一个规则: dx[] ={} 和dy[]={} (都是数组啦!)


使得一个棋子在(x,y)的位置,可以攻击到(x+dx[i] , y + dy[i])位置,可以满足题目一开始给你的棋盘。


============


思路: 暴力。


穷举出所有可能的dx,dy。 然后验证…… 


也就是一开始可以得出所有的dx,dy.


然后带入所有的O所在的位置验证,去掉不合法的dx,dy


然后再验证一次,看看是否覆盖了所有的x。 


就解决了。。


假设S是棋盘总格点数。

得出所有的dx,dy需要S^2。

得出的状态总数为——4S...为啥状态只有4S呢~ 自己想一想就知道啦!我用TreeMap去重了(HashMap太慢!不知道为啥!不懂!)

验证一次需要4S^2


1965 ms强行过……差一点就挂了。。。


当然看到大神的题解啦!

其大神其实是这样想的(http://blog.csdn.net/u011580493/article/details/45462931)—— 比我的方法代码短多啦!也好写!也快!


穷举所有的dx,dy…… (这和我方法思路差不多,但是程序短无数……)得出所有的dx,dy以后,验证一下就行了…… (为毛我是这样求dx,dy没有和大神一样直接穷举呢……果然我还是太笨了)


破烂JAVA代码如下:


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.TreeMap;

public class Main
{
	static int n, m;
	//debug
	static InputReader reader = new InputReader();
	static char g[][] = new char[200][200];
	static char output[][] = new char[200][200];
	static ArrayList<nodexy> piece = new ArrayList<nodexy>(2510);
	static ArrayList<nodexy> attack = new ArrayList<nodexy>(2510);
	
	
	static Comparator<nodexy> cmp = new Comparator<nodexy>() 
	{
		public int compare(nodexy o1, nodexy o2) {
			// TODO Auto-generated method stub
			if (o1.x==o2.x)	return o1.y-o2.y;
			return o1.x-o2.x;
		}
	};
	
	static Map<nodexy, Integer> zuobiao = new TreeMap<nodexy, Integer>(cmp);
	static int vis[][] = new int[200][200];
	
	
	
	
	
	public static void main(String args[])	throws IOException
	{	
		init();
		doit();
	}
	
	
	public static void doit()
	{
		for (int i = 0; i != n; ++ i)
			for (int j = 0; j != n; ++ j)
			{
				if (g[i][j] == 'o')
					piece.add(new nodexy(i,j));
				if (g[i][j] == 'o' || g[i][j] == 'x')
					attack.add(new nodexy(i,j));
			}
		int len1 = piece.size();
		int len2 = attack.size();
	//	System.out.print(len1 + " " + len2);
		for (int i = 0; i != len1; ++ i)
		{
			//System.out.println(i);
			for (int j = 0; j != len2; ++ j)
			{
				int dx = attack.get(j).x - piece.get(i).x  ;
				int dy = attack.get(j).y - piece.get(i).y ;
				if (dx==0 && dy==0)	continue;
			//	System.out.println(dx+" "+dy);
				zuobiao.put(new nodexy(dx, dy), 1);
			}
		}
		/*
		 * debug用,用于输出所有得到的可能性方向。
		{
		Iterator it = zuobiao.entrySet().iterator();
		System.out.println(zuobiao.size());
		while (it.hasNext())
		{
			Map.Entry<nodexy, Integer> ent = (Entry<nodexy, Integer>) it.next();
			System.out.println(ent.getKey().x +" " + ent.getKey().y);
		}
		}
		*/
		
		/*
		 * 注意事项:复制来的字符串,转化的字符串数组,长度变短了!*/
		//System.out.println("len= " + zuobiao.size());
		for (int i = 0; i != len1; ++ i)
		{
			@SuppressWarnings("rawtypes")
			Iterator it = zuobiao.entrySet().iterator();
			while (it.hasNext())
			{
				@SuppressWarnings("unchecked")
				Map.Entry<nodexy, Integer> ent = (Entry<nodexy, Integer>) it.next();
				int wx = piece.get(i).x + ent.getKey().x;
				int wy = piece.get(i).y + ent.getKey().y;
				if (wx <0 || wy <0 || wx >=n || wy >=n)	continue;
				if (g[wx][wy] == '.')	it.remove();
			}
		}

		//根据所有o的位置,判断得出所有被X的地方。
		for (int i = 0; i != n; ++ i)
			for (int j = 0; j != n; ++ j)	vis[i][j] = 0;
		for (int i = 0; i != len1; ++ i)
		{
			@SuppressWarnings("rawtypes")
			Iterator it = zuobiao.entrySet().iterator();
			while (it.hasNext())
			{
				@SuppressWarnings("unchecked")
				Map.Entry<nodexy, Integer> ent = (Entry<nodexy, Integer>) it.next();
				int wx = piece.get(i).x + ent.getKey().x;
				int wy = piece.get(i).y + ent.getKey().y;
				if (wx <0 || wy <0 || wx >=n || wy >=n)	continue;
				vis[wx][wy]=1;	//记录wx,wy的位置被x了
			}
		}
		for (int i = 0; i != n ; ++ i)
			for (int j = 0; j != n; ++ j)
			{
				if (vis[i][j] == 0 && g[i][j] == 'x')//有x的地方没被覆盖
				{
					System.out.println("NO");
					return;
				}
			}
		
		
		System.out.println("YES");
		
		//输出根据方案来输出解
		for (int i = 0; i <= 2 * n - 1; ++ i)
			for (int j = 0; j <= 2 * n - 1; ++ j)	output[i][j] = '.';
		@SuppressWarnings("rawtypes")
		Iterator it = zuobiao.entrySet().iterator();
		while (it.hasNext())
		{
			@SuppressWarnings("unchecked")
			Map.Entry<nodexy, Integer> ent = (Entry<nodexy, Integer>) it.next();
			int wx = n - 1 + ent.getKey().x;
			int wy = n - 1 + ent.getKey().y;
			if (wx <0 || wy <0 || wx >= 2 * n || wy >=2 * n)	continue;
			output[wx][wy] = 'x';
		}
		output[n - 1][n - 1] = 'o';
		for (int i = 0; i != 2 * n -1; ++i)
		{
			for (int j = 0; j != 2 * n - 1; ++ j)
				System.out.print(output[i][j]);
			System.out.println();
		}
	}
	
	public static void init()	throws IOException
	{
		piece.clear();
		n = reader.nextInt();
		for (int i = 0; i != n; ++ i)
			g[i] = (reader.nextTokenizer()).toCharArray();
	}	
}


class nodexy
{
	int x,y;
	nodexy(){}
	nodexy(int xx, int yy)
	{
		x = xx;
		y = yy;
	}
}

class InputReader
{
	public InputReader() {
		// TODO Auto-generated constructor stub
		tokenizer = new StringTokenizer("");
		reader = new BufferedReader(new InputStreamReader(System.in));
	}
	public String nextTokenizer()	throws IOException
	{
		while (!tokenizer.hasMoreTokens())
		{
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
		
	}
	public int nextInt()	throws IOException
	{
		return Integer.valueOf(nextTokenizer());
	}

	StringTokenizer tokenizer;
	BufferedReader	reader;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值