一个人沉迷象棋了,感觉原来的象棋规则没意思,思考更牛逼的象棋规则,从而变象棋界大神。
棋盘是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;
}