在一条无限长的跑道上,有N匹马在不同的位置上出发开始赛马。当开始赛马比赛后,所有的马开始以自己的速度一直匀速前进。每匹马的速度都不一样,且全部是同样的均匀随机分布。在比赛中当某匹马追上了前面的某匹马时,被追上的马就出局。 请问按以上的规则比赛无限长的时间后,赛道上剩余的马匹数量的数学期望是多少
输入描述:
每个测试输入包含1个测试用例 输入只有一行,一个正整数N 1 <= N <= 1000
输出描述:
输出一个浮点数,精确到小数点后四位数字,表示剩余马匹数量的数学期望
输入例子:
1 2
输出例子:
1.0000 1.5000
思路:DP
另外一种方法是直接用推导的数学公式,求每匹马生存下来的概率
最快的马留下来的概率为1
第二块的马只要出现在最快马的后面就能留下,C(n,2)*(n-2)!/n!
其他类似,可得期望是: 1+1/2+1/3+.....+1/n
package l4;
import java.util.*;
/*
* 发现跑得最快的一匹很特殊,它可以追上刚开始再它前面的也就是说最快的后面全部会被淘汰
* 那样就可以把该问题划分为一个更小的子问题,即求前面的结果剩下的马 + 1 就是所有剩下的马的个数
* 自然而然想到了DP
*/
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
int n = sc.nextInt();
long[] frac = new long[1+n];
frac[0] = 1;
for(int i=1; i<1+n; i++)
frac[i] = frac[i-1] * i;
// dp[i][j]表示有i匹马,最后剩下j匹
long[][] dp = new long[1+n][1+n];
for(int i=1; i<1+n; i++) {
dp[i][1] = frac[i-1];
dp[i][i] = 1;
}
for(int i=2; i<1+n; i++)
for(int j=2; j<i; j++) {
for(int k=i-1; k>=j-1; k--)
dp[i][j] += dp[k][j-1] * (frac[i-1]/frac[k]);
}
double rst = 0;
for(int j=1; j<=n; j++)
rst += j * ((0.0 + dp[n][j])/frac[n]);
System.out.printf("%.4f\n", rst);
}
}
}
推箱子
大家一定玩过“推箱子”这个经典的游戏。具体规则就是在一个N*M的地图上,有1个玩家、1个箱子、1个目的地以及若干障碍,其余是空地。玩家可以往上下左右4个方向移动,但是不能移动出地图或者移动到障碍里去。如果往这个方向移动推到了箱子,箱子也会按这个方向移动一格,当然,箱子也不能被推出地图或推到障碍里。当箱子被推到目的地以后,游戏目标达成。现在告诉你游戏开始是初始的地图布局,请你求出玩家最少需要移动多少步才能够将游戏目标达成。
输入描述:
每个测试输入包含1个测试用例 第一行输入两个数字N,M表示地图的大小。其中0<N,M<=8。 接下来有N行,每行包含M个字符表示该行地图。其中 . 表示空地、X表示玩家、*表示箱子、#表示障碍、@表示目的地。 每个地图必定包含1个玩家、1个箱子、1个目的地。
输出描述:
输出一个数字表示玩家最少需要移动多少步才能将游戏目标达成。当无论如何达成不了的时候,输出-1。
输入例子1:
4 4 .... ..*@ .... .X.. 6 6 ...#.. ...... #*##.. ..##.# ..X... .@#...
输出例子1:
3 11
Python 用string代替char吧
n,m=list(map(int,input().strip().split(' ')))
a=[[t for t in input()] for _ in range(n)]
s=set()
t=''.join([''.join(tt) for tt in a])
s.add(t)
rt,ct=t.index('X')//m, t.index('X')%m
rd,cd=t.index('@')//m, t.index('@')%m
q,qq=[(a,rt,ct)],[]
step=succ=0
dirs=[(0,1),(0,-1),(-1,0),(1,0)]
while not succ and q:
while not succ and q:
ss,r,c=q.pop()
for x,y in dirs:
rr,cc=r+x,c+y
if 0<=rr<n and 0<=cc<m:
if ss[rr][cc]!='#' and ss[rr][cc]!='*':
ss2=list([list(tt) for tt in ss])
ss2[r][c]='.'
ss2[rr][cc]='X'
s2 = ''.join([''.join(tt) for tt in ss2])
if s2 not in s:
s.add(s2)
qq.append((ss2,rr,cc))
elif ss[rr][cc]=='*' and 0<=rr+x<n and 0<=cc+y<m and ss[rr+x][cc+y]!='#':
ss2=list([list(tt) for tt in ss])
ss2[r][c]='.'
ss2[rr][cc]='X'
ss2[rr+x][cc+y]='*'
s2 = ''.join([''.join(tt) for tt in ss2])
if s2 not in s:
s.add(s2)
qq.append((ss2,rr,cc))
if rr+x==rd and cc+y==cd:
succ = 1
break
q,qq=qq,q
step+=1
print(step if succ else -1)
在一个N*N的数组中寻找所有横,竖,左上到右下,右上到左下,四种方向的直线连续D个数字的和里面最大的值
输入描述:
每个测试输入包含1个测试用例,第一行包括两个整数 N 和 D : 3 <= N <= 100 1 <= D <= N 接下来有N行,每行N个数字d: 0 <= d <= 100
输出描述:
输出一个整数,表示找到的和的最大值
输入例子1:
4 2 87 98 79 61 10 27 95 70 20 64 73 29 71 65 15 0
输出例子1:
193
先求出所有的,filter掉len小于m的,省去下标控制
以4个角点为起始位置,枚举
n,m=list(map(int,input().strip().split(' ')))
a=[list(map(int,input().strip().split(' '))) for _ in range(n)]
res=[]
for i in range(n):
res.append(a[i])
res.append([a[j][i] for j in range(n)])
for i in range(0,n):
res.append([a[i-p][p] for p in range(i+1)])
res.append([a[n-1-p][n-1-i+p] for p in range(i+1)])
res.append([a[n-1-i+p][p] for p in range(i+1)])
res.append([a[p][n-1-i+p] for p in range(i+1)])
res=list(filter(lambda t:len(t)>=m, res))
#print(res)
def f(t):
return [sum(t[i:i+m]) for i in range(0,n-m+1)]
res=list(map(f, res))
#print(res)
res=list(map(max, res))
#print(res)
print(max(res))