百度——罪犯转移、裁剪网格纸、钓鱼比赛、蘑菇阵

题目一:罪犯转移

C市现在要转移一批罪犯到D市,C市有n名罪犯,按照入狱时间有顺序,另外每个罪犯有一个罪行值,值越大罪越重。现在为了方便管理,市长决定转移入狱时间连续的c名犯人,同时要求转移犯人的罪行值之和不超过t,问有多少种选择的方式? 

输入描述:
第一行数据三个整数:n,t,c(1≤n≤2e5,0≤t≤1e9,1≤c≤n),第二行按入狱时间给出每个犯人的罪行值ai(0≤ai≤1e9)
输出描述:
一行输出答案。
输入例子:
3 100 2
1 2 3
输出例子:
2
解析:考察数组的滑动窗口机制,否则会超时。
注:使用BufferedReader读取数据的时候一定要Throws Exception
import java.util.*;
import java.io.*;
public class Main{
    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String s="";
        while((s=br.readLine())!=null)
            {
            String[] strs=s.split(" ");//0为数组长度,1为数组和上限,2为子数组长度
            int n=Integer.parseInt(strs[0]);
            int t=Integer.parseInt(strs[1]);
            int c=Integer.parseInt(strs[2]);
            int[] data=new int[n];
            s=br.readLine();
            strs=s.split(" ");
            for(int i=0;i<n;i++)
                {
                data[i]=Integer.parseInt(strs[i]);
            }
            int count=help(data,c,t);
            System.out.println(""+count);
        }
        br.close();
    }
    //滑动窗口机制,否则会超时。
    public static int help(int[] data,int c,int t)
        {
        int count=0;
        int cursum=0;
        for(int i=0;i<c;i++)
            {
            cursum+=data[i];
        }
        if(cursum <= t)
            count++;
        for(int i=c;i<data.length;i++)
            {
            cursum-=data[i-c];
            cursum+=data[i];
            if(cursum <= t)
                count++;
        }
        return count;
    }
}



题目二:裁剪网格纸

度度熊有一张网格纸,但是纸上有一些点过的点,每个点都在网格点上,若把网格看成一个坐标轴平行于网格线的坐标系的话,每个点可以用一对整数x,y来表示。度度熊必须沿着网格线画一个正方形,使所有点在正方形的内部或者边界。然后把这个正方形剪下来。问剪掉正方形的最小面积是多少。 
输入描述:
第一行一个数n(2≤n≤1000)表示点数,接下来每行一对整数xi,yi(-1e9<=xi,yi<=1e9)表示网格上的点
输出描述:
一行输出最小面积
输入例子:
2
0 0
0 3
输出例子:
9
解析:求出x,y坐标最大距离中的较大者即可。本解法性能不好,其实只记录就可以了,不用排序。
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        while(in.hasNext())
            {
            int rows=in.nextInt();
            int[] left=new int[rows];
            int[] right=new int[rows];
            for(int i=0;i<rows;i++)
                {
                left[i]=in.nextInt();
                right[i]=in.nextInt();
            }
            Arrays.sort(left);
            Arrays.sort(right);
            int max_left=left[rows-1]-left[0];
            int max_right=right[rows-1]-right[0];
            int max=Math.max(max_left,max_right);
            System.out.println(""+max*max);
        }
        in.close();
    }
}

题目三:钓鱼比赛

ss请cc来家里钓鱼,鱼塘可划分为n*m的格子,每个格子每分钟有不同的概率钓上鱼,cc一直在坐标(x,y)的格子钓鱼,而ss每分钟随机钓一个格子。问t分钟后他们谁至少钓到一条鱼的概率大?为多少?

输入描述:
第一行五个整数n,m,x,y,t(1≤n,m,t≤1000,1≤x≤n,1≤y≤m);
接下来为一个n*m的矩阵,每行m个一位小数,共n行,第i行第j个数代表坐标为(i,j)的格子钓到鱼的概率为p(0≤p≤1)
输出描述:
输出两行。第一行为概率大的人的名字(cc/ss/equal),第二行为这个概率(保留2位小数)
输入例子:
2 2 1 1 1
0.2 0.1
0.1 0.4
输出例子:
equal
0.20
注:1.BufferedReader读取数据时要抛出异常。
       2.保留两位小数的输出方法System.out.printf("%.2f\n",decimal);
import java.util.*;
import java.io.*;
public class Main{
    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String s="";
        while((s=br.readLine())!=null)
            {
            String[] strs=s.trim().split(" ");
            int n=Integer.parseInt(strs[0]);
            int m=Integer.parseInt(strs[1]);
            int x=Integer.parseInt(strs[2]);
            int y=Integer.parseInt(strs[3]);
            int t=Integer.parseInt(strs[4]);
            double[][] matrix=new double[n][m];
            //记录矩阵所有元素的和,为ss做准备
            double sum=0;
            //矩阵赋值
            for(int i=0;i<n;i++)
                {
                s=br.readLine();
                strs=s.split(" ");
                for(int j=0;j<m;j++)
                    {
                    matrix[i][j]=Double.parseDouble(strs[j]);
                    sum+=matrix[i][j];
                }
            }
            //cc钓到鱼的概率
            double cc=1-Math.pow((1-matrix[x-1][y-1]),t);
            //ss钓到鱼的概率
            double ss=1-Math.pow((1-(sum/(n*m))),t);
            if(cc - ss > 0)//cc概率大
                {
                System.out.println("cc");
                System.out.printf("%.2f\n", cc);
            }
            else if(ss - cc > 0)//ss概率大
                {
                System.out.println("ss");
                 System.out.printf("%.2f\n", ss);
            }
            else//一样大
                {
                System.out.println("equal");
                System.out.printf("%.2f\n", cc);
            }
        }
        br.close();
    }
}


题目四:蘑菇阵

现在有两个好友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(2 ≤ N,M ≤ 20, k ≤ 100),N,M为草地大小,接下来K行,每行两个整数x,y,代表(x,y)处有一个蘑菇。
输出描述:
输出一行,代表所求概率(保留到2位小数)
输入例子:
2 2 1
2 1
输出例子:
0.50
这道题就没什么好说的了,不能用可行的路数/总路数,反正绕的一比。
import java.util.*;
import java.io.*;
public class Main{
    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String s="";
        while((s=br.readLine())!=null){
            String[] strs=s.split(" ");
            int n=Integer.parseInt(strs[0]);
            int m=Integer.parseInt(strs[1]);
            int k=Integer.parseInt(strs[2]);
            int[][] matrix=new int[n][m];
            for(int i=0;i<k;i++)
                {
                s=br.readLine();
                strs=s.split(" ");
                int x=Integer.parseInt(strs[0])-1;
                int y=Integer.parseInt(strs[1])-1;
                matrix[x][y]++;
            }
            double d=help(matrix);
            System.out.printf("%.2f\n",d);
        }
        br.close();
    }
    //可行的路数
    public static double help(int[][] matrix)
        {
        if(matrix[0][0]!=0||matrix[matrix.length-1][matrix[0].length-1]!=0)
            return 0;
        int rows=matrix.length;
        int cols=matrix[0].length;
        double[][]dp=new double[rows][cols];//dp[i][j]表示matrix[i][j]的可达概率;
        dp[0][0]=1;
        //初始化
        for(int j=1;j<cols;j++)
            {
            if(matrix[0][j]!=0)//若有蘑菇则为0,;
                dp[0][j]=0;
            else if(rows!=1)//若有多行,在前一格有0.5的概率向下了,所以乘以0.5
                dp[0][j]=0.5*dp[0][j-1];
                else//若只有一行,则没有抉择,不用乘以0.5
                dp[0][j]=dp[0][j-1];
        }
        for(int i=1;i<rows;i++)
            {
            if(matrix[i][0]!=0)
                dp[i][0]=0;
            else if(cols!=1)
                dp[i][0]=0.5*dp[i-1][0];
                else
                dp[i][0]=dp[i-1][0];
        }
        //general
        for(int i=1;i<rows;i++)
            {
            for(int j=1;j<cols;j++)
                {
                if(matrix[i][j]!=0)
                    dp[i][j]=0;
                else if(i < rows-1&&j < cols-1)
                    dp[i][j]=0.5*dp[i-1][j]+0.5*dp[i][j-1];
                    else if(i == rows-1&&j < cols-1)
                    dp[i][j]=dp[i][j-1]+0.5*dp[i-1][j];
                    else if(j == cols-1&&i < rows-1)
                    dp[i][j]=dp[i-1][j]+0.5*dp[i][j-1];
                    else
                    dp[i][j]=dp[i-1][j]+dp[i][j-1];
            }
        }
        return dp[rows-1][cols-1];
    }
  
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值