计蒜客蓝桥B组模拟赛五-C. 连连看

连连看是一款非常有意思的游戏。

我们可以把任意两个在图的在边界上的相同的方格一起消掉,比如把两个 44 消掉以后,

每次消掉两个方格的时候,都有会获得一个分数,第 ii 次消的分数为 i \timesi× 方格的值。比如上面的消法,是第一次消,获得的分数为 1 \times 4 = 41×4=4

请你帮忙最优操作情况下,获得的分数最多为多少。

思路:

只有5个不同的数,所以就可以去维护5个集合,(k)每个集合中存储可以当前在边界上且其值为当前值(k)的坐标,然后不断的深搜回溯即可。

写Java的自己真的菜,写好久,,还很多bug,还不晓得Java如何判断死循环?

代码:

import java.util.ArrayList;

public class Main3 {

	private static class Node {
		int x, y;
		public Node(int x, int y) {
			this.x = x;
			this.y = y;
		}
		public String toString() {
			return x + ":" + y;
		}
	}
	private static ArrayList<Node>[] a = new ArrayList[10];
	public static int[][] t = { {}, 
								{0, 1, 4, 2, 5}, 
								{0, 2, 1, 2, 1}, 
								{0, 3, 1, 3, 2}, 
								{0, 2, 5, 3, 4}
							  };
	public static boolean[][] vis = new boolean[5][5];
	public static void init() {
		for(int i = 1; i <= 5; ++i) {
			a[i] = new ArrayList<>();
		}
		
		a[t[1][1]].add(new Node(1, 1));
		a[t[1][4]].add(new Node(1, 4));
		a[t[4][1]].add(new Node(4, 1));
		a[t[4][4]].add(new Node(4, 4));
		for(int i = 1; i <= 4; ++i) {
			vis[i][1] = vis[1][i] = true;
			vis[i][4] = vis[4][i] = true;
			if(i != 1 && i != 4) {
				a[t[1][i]].add(new Node(1, i));
				a[t[i][1]].add(new Node(i, 1));
				a[t[4][i]].add(new Node(4, i));
				a[t[i][4]].add(new Node(i, 4));
			}
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		init();
		ans = 0;
		dfs(1, 0);
		System.out.println(ans);
	}
	private static int ans;
	private static void dfs(int x, int val) {
//		System.out.println(x);
//		System.out.println(x + "--->");
//		for(int i = 1; i <= 5; ++i) {
//			for(int j = 0; j < a[i].size(); ++j) {
//				System.out.print(a[i].get(j) + ", ");
//			}
//			System.out.println();
//		}
//		System.out.println("------");
			if(ans < val) {
				ans = val;
			}
		for(int i = 1; i <= 5; ++i) {
			if(a[i].size() < 2) {
				continue;
			}
			for(int j = 0; j < a[i].size(); ++j) {
				for(int k = j+1; k < a[i].size(); ++k) {
					ArrayList<Node>[] tmp = new ArrayList[10];
					ArrayList<Node> id1 = new ArrayList<>();
					ArrayList<Node> id2 = new ArrayList<>();
					Node tmp1 = a[i].get(j), tmp2 = a[i].get(k);

					for(int ii = 1; ii <= 5; ++ii) {
						tmp[ii] = new ArrayList<>(a[ii]);
					}
					
					int x1 = a[i].get(j).x, x2 = a[i].get(k).x;
					int y1 = a[i].get(j).y, y2 = a[i].get(k).y;
					if(check(x1+1, y1)) {
						id1.add(new Node(x1+1, y1));
					}if(check(x1, y1+1)) {
						id1.add(new Node(x1, y1+1));
					}if(check(x1-1, y1)) {
						id1.add(new Node(x1-1, y1));
					}if(check(x1, y1-1)) {
						id1.add(new Node(x1, y1-1));
					}
					for(int o = 0; o < id1.size(); ++o) {
						vis[id1.get(o).x][id1.get(o).y] = true;
						int vv = t[id1.get(o).x][id1.get(o).y];
						a[vv].add(new Node(id1.get(o).x, id1.get(o).y));
					}
					if(check(x2+1, y2)) {
						id2.add(new Node(x2+1, y2));
					}if(check(x2, y2+1)) {
						id2.add(new Node(x2, y2+1));
					}if(check(x2-1, y2)) {
						id2.add(new Node(x2-1, y2));
					}if(check(x2, y2-1)) {
						id2.add(new Node(x2, y2-1));
					}
					for(int o = 0; o < id2.size(); ++o) {
						vis[id2.get(o).x][id2.get(o).y] = true;
						int vv = t[id2.get(o).x][id2.get(o).y];
						a[vv].add(new Node(id2.get(o).x, id2.get(o).y));
					}
					
					a[i].remove(tmp1);
					a[i].remove(tmp2);
					dfs(x+1, val+i*x);
					
					for(int o = 0; o < id1.size(); ++o) {
						vis[id1.get(o).x][id1.get(o).y] = false;
					}
					for(int o = 0; o < id2.size(); ++o) {
						vis[id2.get(o).x][id2.get(o).y] = false;
					}

					for(int ii = 1; ii <= 5; ++ii) {
						a[ii] = new ArrayList<>(tmp[ii]);
					}
					
				}
			}
		}
	}
	
	
	private static boolean check(int x, int y) {
		if(x < 1 || x > 4 || y < 1 || y > 4) {
			return false;
		}
		if(vis[x][y]) {
			return false;
		}
		return true;
	}
	
}

继续加油~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值