2018 拼多多

六一儿童节,老师带了很多好吃的巧克力到幼儿园。每块巧克力j的重量为w[j],对于每个小朋友i,当他分到的巧克力大小达到h[i] (即w[j]>=h[i]),他才会上去表演节目。老师的目标是将巧克力分发给孩子们,使得最多的小孩上台表演。可以保证每个w[i]> 0且不能将多块巧克力分给一个孩子或将一块分给多个孩子。 

输入描述:
第一行:n,表示h数组元素个数
 第二行:n个h数组元素
 第三行:m,表示w数组元素个数
 第四行:m个w数组元素


输出描述:
上台表演学生人数

输入例子1:
3 
 2 2 3
 2
 3 1 

输出例子1:
1

思路:贪心,对糖果排序,用当前的糖果满足需求量最大的学生

package l3;


import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] a = new int[n];
		for(int i=0; i<n; i++)a[i]=sc.nextInt();
		int m = sc.nextInt();
		int[] b = new int[m];
		for(int i=0; i<m; i++)b[i]=sc.nextInt();
		
		Arrays.sort(a);
		Arrays.sort(b);
		
		int ret = 0, p = n-1;
		for(int i=m-1; i>=0; i--) {
			while(p>=0 && b[i] < a[p])	p--;
			if(p == -1)		break;
			
			ret ++;
			p --;
		}
		
		System.out.println(ret);
	}
}




假设一个探险家被困在了地底的迷宫之中,要从当前位置开始找到一条通往迷宫出口的路径。迷宫可以用一个二维矩阵组成,有的部分是墙,有的部分是路。迷宫之中有的路上还有门,每扇门都在迷宫的某个地方有与之匹配的钥匙,只有先拿到钥匙才能打开门。请设计一个算法,帮助探险家找到脱困的最短路径。如前所述,迷宫是通过一个二维矩阵表示的,每个元素的值的含义如下 0-墙,1-路,2-探险家的起始位置,3-迷宫的出口,大写字母-门,小写字母-对应大写字母所代表的门的钥匙 

输入描述:
迷宫的地图,用二维矩阵表示。第一行是表示矩阵的行数和列数M和N
后面的M行是矩阵的数据,每一行对应与矩阵的一行(中间没有空格)。M和N都不超过100, 门不超过10扇。


输出描述:
路径的长度,是一个整数

输入例子1:
5 5
02111
01a0A
01003
01001
01111

输出例子1:
7


思路:BFS,但是自己写下来100+行,而且TLE

package l4;


import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;

public class CopyOfMain {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(), m = sc.nextInt();
		sc.nextLine();
		char[][] a = new char[n][m];
		int x = -1, y = -1;
		for(int i=0; i<n; i++) {
			String s = sc.nextLine();
			a[i] = s.toCharArray();
			if(s.indexOf('2') != -1) {
				x = i;
				y = s.indexOf('2');
			}
		}
		
		Set<String> visited = new HashSet<String>();
		int step = 0;
		Queue<Object[]> q = new LinkedList<Object[]>();
		Queue<Object[]> qq= new LinkedList<Object[]>();
		q.add(new Object[]{x,y,""});
		visited.add(x +" "  + y + " " + getKeys(a, x, y, ""));
		
		while(true) {
			while(!q.isEmpty()) {
				Object[] t = q.remove();
				int tx = (Integer) t[0], ty = (Integer) t[1];
				String keys = (String) t[2];
				
				if(a[tx][ty] == '3') {
					System.out.println(step);
					return;
				}
				
				if(tx > 0 && canPass(a, tx-1, ty, keys)) {
					String tmpKeys = getKeys(a, tx-1, ty, keys);
					String tmp = tx-1 + " " + ty + " " + tmpKeys;
					if(!visited.contains(tmp))	{
						visited.add(tmp);
						qq.add(new Object[]{tx-1, ty, tmpKeys});	// 这里应该放keys
					}
				}
				
				if(ty > 0 && canPass(a, tx, ty-1, keys)) {
					String tmpKeys = getKeys(a, tx, ty-1, keys);
					String tmp = tx + " " + (ty-1) + " " + tmpKeys;
					if(!visited.contains(tmp))	{
						visited.add(tmp);
						qq.add(new Object[]{tx, ty-1, tmpKeys});
					}
				}
				
				if(tx < n-1 && canPass(a, tx+1, ty, keys)) {
					String tmpKeys = getKeys(a, tx+1, ty, keys);
					String tmp = tx+1 + " " + ty + " " + tmpKeys;
					if(!visited.contains(tmp))	{
						visited.add(tmp);
						qq.add(new Object[]{tx+1, ty, tmpKeys});
					}
				}
				
				if(ty < m-1 && canPass(a, tx, ty+1, keys)) {
					String tmpKeys = getKeys(a, tx, ty+1, keys);
					String tmp = tx + " " + (ty+1) + " " + tmpKeys;
					if(!visited.contains(tmp))	{
						visited.add(tmp);
						qq.add(new Object[]{tx, ty+1, tmpKeys});
					}
				}
				
			}
			
			q = qq;
			qq = new LinkedList<Object[]>();
			step ++;
			if(q.isEmpty())	break;
		}
		
		System.out.println(-1);
	}

	private static boolean canPass(char[][] a, int i, int j, String keys) {
		return a[i][j]=='1' || a[i][j]=='2' || a[i][j]=='3' || (a[i][j]>='a'&&a[i][j]<='z') 
					|| (a[i][j]>='A'&&a[i][j]<='Z'&&keys.indexOf(a[i][j])!=-1);
	}

	private static String getKeys(char[][] a, int i, int j, String keys) {
		if(a[i][j]>='a' && a[i][j]<='z')	
			keys += (""+a[i][j]).toUpperCase();
		if(a[i][j]>='A' && a[i][j]<='Z') {
			int idx = keys.indexOf(a[i][j]);
			if(idx != -1) keys = keys.substring(0, idx) + keys.substring(idx+1);
		}
		return keys;
	}
}

有2个trick

1. 用integer表示10中=种钥匙

2. 因为时间是限制AC的主要因素,用数组比HashSet好

package l4;


import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

/*
 * 写博客的时候看下牛客的讨论区
 * 用数组可AC
 * 
 * 此可以作为BFS的模板
 * 
 * 反正key最多10个,用int足矣
 * 状态也可以用个数组表示,
 */
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(), m = sc.nextInt();
		sc.nextLine();
		char[][] a = new char[n][m];
		int x = -1, y = -1;
		for(int i=0; i<n; i++) {
			String s = sc.nextLine();
			a[i] = s.toCharArray();
			if(s.indexOf('2') != -1) {
				x = i;
				y = s.indexOf('2');
			}
		}
		
		boolean[][][] visited = new boolean[n][m][1100];
		int step = 0;
		Queue<int[]> q = new LinkedList<int[]>();
		Queue<int[]> qq= new LinkedList<int[]>();
		q.add(new int[]{x,y,0});
		visited[x][y][0] = true;
		int[][] next = {{-1,0}, {0,-1}, {1,0}, {0,1}};
		
		while(true) {
			while(!q.isEmpty()) {
				int[] t = q.remove();
				for(int i=0; i<4; i++) {
					int newx = t[0]+next[i][0], newy = t[1]+next[i][1], keys = t[2];
					if(newx<0||newx>=n||newy<0||newy>=m||a[newx][newy]=='0') continue;
					if(a[newx][newy]=='3') {
						System.out.println(step+1);
						return;
					} else if(a[newx][newy]>='a' && a[newx][newy]<='z') {
						// 钥匙可以重复利用
						keys = (keys | (1<<(a[newx][newy]-'a')));
					} else if(a[newx][newy]>='A' && a[newx][newy]<='Z') {
						if((keys & (1<<(a[newx][newy]-'a'))) == 0) 
							continue;
					}
					
					if(visited[newx][newy][keys])	continue;
					visited[newx][newy][keys] = true;
					qq.add(new int[]{newx, newy, keys});
				}
			}
			
			// q,qq可以合并为一个linkedlist,把step信息放到数组里面即可
			q = qq;
			qq = new LinkedList<int[]>();
			step++;
		}
	}

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值