20210318牛客笔试模拟小记

emm

记录一下题目

1.最差运气

有一款游戏,过关的方式是按按钮。
游戏一共有1关,每一关有个按钮,其中只有唯一—个按钮是可以通关的,按下其他的按钮游戏就会失败。
好在这个游戏可以重来,而且由于设计者的疏忽,每一关的通关按钮是不变的,所以你可以记住前几关的按钮,重来时就可以直接通关。
但是…你的运气似乎用在了其他地方,你使用了最多的按按钮次数才成功通关。
求这个最多的按按钮次数吧!
20210318牛客笔试模拟小记_第1张图片



思路:普通计算,理清逻辑,一步一步往下写,先求失败次数,再求最后通过次数

//核心代码模式
public long findMaxButtons(int[] a)
{
    long res = a.length;	//最后通过时按下的次数
    for(int i = 0; i < a.length ; i++)
    {
        res += (long) (a[i] - 1) * i;	//累加失败次数:第i关失败a[i] - 1次,每次都要按i次按钮
    }
    return res;
}

2. 刷墙

最近小明搬到了新家,他正在粉刷墙壁,但是不幸的是他粉刷的墙壁并不理想。他的墙壁是一个长度为n的格子,每个格子用0表示红色,用1表示蓝色。现在墙壁是一个非常混乱的颜色。他想将墙壁涂成左边全是蓝色右边全是红色,可以将墙壁刷成全是红色或者蓝色。请问他至少需要粉刷多少个格子墙壁刷成他想要的样子?
20210318牛客笔试模拟小记_第2张图片



思路: 枚举 + 前缀和

枚举所有情况,选择最少次数(暴力方法)

使用前缀和进行优化(预处理减少重复计算次数)

前缀和:在经过一次O(n)的预处理后,可以以O(1)查询目标区间的和

import java.util.Scanner;
public class Main{
    public static void main(String[] args)
    {
     	Scanner in = new Scanner(System.in);
        //获取输入
        int n = in.nextInt();
        String str = " " + in.next();
        int[] sum = new int[n+1];
        for(int i = 1; i <= n; i++)
        {
            sum[i] = sum[i-1] + s.charAt(i) - '0';
        }
        //枚举所有边界情况,寻找最小值
        int res = n;	//找最小,初始化最大
        for(int i = 0; i <= n; i++)		//注意,从0-n
        {
            //[1, i]中0的个数: i - sum[i]
            //[i+1 , n]中1的个数: sum[n] - sum[i]
            res = Math.min(res , i - sum[i] + sum[n] - sum[i]);
        }
        //输出
        System.out.println(res);
    }
}

3.胜者为王

小明,小王,小李三人正在进行一个游戏。游戏有n个回合,每个人都有一个字符串,三人的字符串长度相等。每个回合他们必须更改自己字符串中的一个字母。最后每个人的分数是字自己的字符串中出现字符最多的字母的数量。分数最高者获胜,输出获胜者名字,小明获胜输出xiaoming,小王获胜输出xiaowang,小李获胜输出xiaoli,如果有两个或者两个以上相同的最高分输出draw。
20210318牛客笔试模拟小记_第3张图片



思路:贪心思想对于每个回合分配到的字符串,每次更改其他字符为出现次数最多的字符

设出现最多字符为x,n回合,则分数 = min(x + n , len);

//考虑一种情况:如果 x + n > 字符串长度,会不会必须反转x : 不必,只需不断更新最后一个字符为其他字符,在最后一个回合更换为x,因此,分数最大为字符串长度

//编码实现
import java.util.Scanner;
public class Main{
    public static void main(String[] args)
    {
   		Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        String s1 = in.nextLine();
        String s2 = in.nextLine();
        String s3 = in.nextLine();
		int len = s1.length();
        int x = 0, y = 0 , z = 0;	//对应s1, s2, s3
        //计算s1中字符出现的最多次数
        int[] cnt = new int[256];
        for(int i = 0; i < len; i++)
            x = Math.max(x , ++cnt[s1.charAt(i)]);	//char自动转型为int
        for(int i = 0; i < 256; i++)
            cnt[i] = 0;				//清0,重复利用数组空间
        //计算s2
        for(int i = 0; i < len; i++)
            y = Math.max(y , ++cnt[s2.charAt(i)]);
        for(int i = 0; i < 256; i++)
            cnt[i] = 0;
        //计算s3
        for(int i = 0; i < len; i++)
            z = Math.max(z , ++cnt[s3.charAt(i)]);
        for(int i = 0; i < 256; i++)
            cnt[i] = 0;
        //计算n回合得分
        x = Math.max(x + n , len);
        y = Math.max(y + n , len);
        z = Math.max(z + n , len);
        //输出结果
        if(x > y && x > z)
            System.out.println("xiaoming");
        else if(y > x && y > z)
            System.out.println("xiaowang");
        else if(z > x && z > y)
            System.out.println("xiaoli");
        else
            System.out.println("draw");
    }   
}

你可能感兴趣的:(面试,算法)