题目一:
现在有两个好友A和B,住在一片长有蘑菇的由n*m个方格组成的草地,A在(1,1),B在(n,m)。现在A想要拜访B,由于她只想去B的家,
所以每次她只会走(i,j+1)或(i+1,j)这样的路线,在草地上有k个蘑菇种在格子里(多个蘑菇可能在同一方格),
问:A如果每一步随机选择的话(若她在边界上,则只有一种选择),那么她不碰到蘑菇走到B的家的概率是多少?
输入描述:
第一行N,M,K(1 ≤ N,M ≤ 20, k ≤ 100),N,M为草地大小,接下来K行,每行两个整数x,y,代表(x,y)处有一个蘑菇。
输出描述:
输出一行,代表所求概率(保留到2位小数)
示例1
输入
2 2 1 2 1
输出
0.50
----------------------------------------------------------------------------------------------------------------------------------------------------------------
思路:
用map[i][j]表示蘑菇的位置,用cw[i][j]用来保存到(i,j)点的概率。因为起点为(0,0),终点在第一象限,所以一开始,走的方向
为两个,向上或者向下。所以(i,j)点的位置概率为它之前的点的概率之和。(i,j)点之前的坐标可以表示为(i-1,j)和(i,j-1)。除此之外,还有一个条件,
就是该点是否在边界上,如果在边界上,根据题意,他只有一种选择,即概率为1,要么不在边界,则概率为0.5。
代码:
import java.util.Scanner;
public class CountBroohPath {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()){
int n = scanner.nextInt();
int m = scanner.nextInt();
int k = scanner.nextInt();
boolean[][] map = new boolean[n][m];
//题目中描述出发点为(0,0)
for(int i=0;i<k;i++){
//由于题目中描述数组从1开始,所以在这里减1
int x = scanner.nextInt()-1;
int y = scanner.nextInt()-1;
//map用来保存蘑菇所在的点
map[x][y]=true;
}
double[][] cw = new double[n][m];
//cw用来保存(i,j)节点的概率。
cw[0][0]=1;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
//如果该节点存在蘑菇,则这条路不同,所以赋值0
if(map[i][j])
cw[i][j]=0;
else if (i==0 && j==0){}
else {
//j-1<0表示到底边了,i+1<n表示还没到最右边,i-1<0表示还没到最左边,到边的话概率为1,不到边的话概率为0.5
//这里加号分成两部分,一部分是按照下右方向走,一个是按照左上方向
cw[i][j] = (j-1<0?0:(i+1<n?cw[i][j-1]*0.5:cw[i][j-1]))+
(i-1<0?0:(j+1<m?cw[i-1][j]*0.5:cw[i-1][j]));
}
}
}
double res= cw[n-1][m-1];
System.out.println(String.format("%.2f", res));
}
}
}
题目二:
现在有一个城市销售经理,需要从公司出发,去拜访市内的商家,已知他的位置以及商家的位置,但是由于城市道路交通的原因,他只能在左右中选择一个方向,在上下中选择一个方向,现在问他有多少种方案到达商家地址。
给定一个地图map及它的长宽n和m,其中1代表经理位置,2代表商家位置,-1代表不能经过的地区,0代表可以经过的地区,请返回方案数,保证一定存在合法路径。保证矩阵的长宽都小于等于10。
测试样例:
[[0,1,0],[2,0,0]],2,3
返回:2
--------------------------
-----------------------------------------------------------------------------------------------
思路:
要求从某点到某点的可供选择的路径数。首先从题意中我们可以知道,从起点开始,只有横竖两个方向。
我们可以用map[x][y]表示从起点到当前点的路径数,那么当前的值可以由上一次两个方向的路径数相加得到。
首先可以知道,如果当前点与前一点处于同一行 或者同一列,很显然那路径数就是1,如果与起点处于不同行列的话,
那么map[x][y]=map[x-xd]+map[x][y-yd]。
代码:
public static int countPath(int[][] map, int n, int m){
int x1=0;
int y1 =0;
int x2 = 0;
int y2 = 0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
//找到经理所在位置
if(map[i][j] ==1){
x1 = i;
y1 = j;
}
//找到客户所在位置
else if(map[i][j] ==2){
x2 = i;
y2 = j;
}
}
}
//决定x轴和y轴走的方向,
int yd = y1 >y2?-1:1;
int xd = x1>x2?-1:1;
//初始x的位置为经理的x轴位置,每次走xd,当x不等于x2时,执行循环。因为for循环的执行过程,所以循环结束判断需要给x2+xd。
for(int x = x1; x!=x2+xd; x+=xd){
for(int y=y1;y!=y2+yd;y+=yd){
//如果是沿着直线走,则路线为1
if(x==x1||y==y1){
map[x][y] = map[x][y] == -1?0:1;
System.out.println("map["+x+"]["+y+"]: "+map[x][y]);
continue;
}
//如果没有按直线走。则当前可达时,方案数= 上一个(注意是-)沿着x方向走到当前点的方案数 + 上一点沿着y方向走到当前点的方案数。
map[x][y]=map[x][y]==-1?0:map[x-xd][y]+map[x][y-yd];
}
}
return map[x2][y2];
}
题目三
C市现在要转移一批罪犯到D市,C市有n名罪犯,按照入狱时间有顺序,另外每个罪犯有一个罪行值,值越大罪越重。现在为了方便管理,市长决定转移入狱时间连续的c名犯人,同时要求转移犯人的罪行值之和不超过t,问有多少种选择的方式?
输入描述:
第一行数据三个整数:n,t,c(1≤n≤2e5,0≤t≤1e9,1≤c≤n),第二行按入狱时间给出每个犯人的罪行值ai(0≤ai≤1e9)
输出描述:
一行输出答案。
-------------
-------------
-------------
-------------
-------------
-------------
-------------
-------------
代码
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
while(in.hasNext()){
int n = in.nextInt();//n个人
int t = in.nextInt();//
int c = in.nextInt();//连续c名
int[] a = new int[n];
for(int i = 0;i<n;i++){
a[i] = in.nextInt();
}
int count = 0;
int tempt = 0;
for(int i = 0;i<c;i++){
tempt += a[i];
}
if(tempt<=t)
count++;
for(int i = c;i<a.length;i++){
tempt = tempt+a[i]-a[i-c];
if(tempt<=t)
count++;
}
System.out.println(count);
}
}
}