牛客编程巅峰赛S2第7场

牛牛爱喝酒

链接:https://ac.nowcoder.com/acm/contest/9752/A

题目描述

牛牛是一个酒鬼,非常爱喝酒,一瓶酒m元钱,两个酒瓶可以换一瓶酒,四个瓶盖可以换一瓶酒,现在有 n 元钱,求最多可以喝多少瓶酒?

(注:没有借贷功能,即最终不允许借一瓶酒、喝完后拿酒瓶兑换归还的操作)

签到题:

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回牛牛能喝的最多的酒
     * @param m int整型 酒单价
     * @param n int整型 牛牛的现金
     * @return int整型
     */
    public int countWine (int m, int n) {
        // write code here
        int ans=n/m,b=n/m,c=n/m;
        while(b>=2||c>=4){
            int x=b/2+c/4;
            b=b%2+x;
            c=c%4+x;
            ans+=x;
        }
        return ans;
    }
}

牛牛的独特子序列

链接:https://ac.nowcoder.com/acm/contest/9752/B

题目描述

牛牛现在有一个长度为len只包含小写字母‘a’-'z'的字符串x,他现在想要一个特殊的子序列,这个子序列的长度为3*n(n为非负整数),子序列的第[1,n]个字母全部为‘a’,子序列的[n+1,2*n]个字母全部为‘b’,子序列的[2*n+1,3*n]个字母全部为‘c’,牛牛想知道最长的符合条件的独特子序列的长度是多少。

两种解法,一是二分O(nlogn),二是双指针O(n)

二分,下界是0,上界是abc出现最小次数

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param x string字符串 
     * @return int整型
     */
    public int Maximumlength (String x) {
        // write code here
        int n=x.length();
        int r=0;
        int a=0,b=0,c=0;
        char[] ch=x.toCharArray();
        for(int i=0;i<n;++i){
            switch(ch[i]){
                case 'a':a++;break;
                case 'b':b++;break;
                case 'c':c++;break;
            }   
        }
        r=Math.min(a,b);
        r=Math.min(r,c);
        int l=0;
        while(l<=r){
            int mid=(l+r)>>1;
            if(check(ch,mid)){
                l=mid+1;
            }else{
                r=mid-1;
            }
        }
        if(r>0)
            return r*3;
        return 0;
    }
    private boolean check(char[] s,int n){
        int cur=0,i=0;
        for(;i<s.length&&cur!=n;++i){
            if(s[i]=='a')
                cur++;
        }
        for(;i<s.length&&cur!=2*n;++i){
            if(s[i]=='b')
                cur++;
        }
        for(;i<s.length&&cur!=3*n;++i){
            if(s[i]=='c')
                cur++;
        }
        return cur==3*n;
    }
}

双指针,前后两个指针遍历a和c,然后对b记录前缀和

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param x string字符串 
     * @return int整型
     */
    public int Maximumlength (String x) {
        // write code here
        List<Integer> A=new ArrayList<Integer>();
        List<Integer> C=new ArrayList<Integer>();
        int n=x.length();
        int[] pre=new int[n+1];
        for(int i=1;i<=n;++i){
            pre[i]=pre[i-1];
            if(x.charAt(i-1)=='a'){
                A.add(i-1);
            }
            if(x.charAt(i-1)=='b'){
                pre[i]++;
            }
            if(x.charAt(i-1)=='c'){
                C.add(i-1);
            }
        }
        Collections.reverse(C);
        int ans=0;
        for(int i=0;i<A.size()&&i<C.size();++i){
            if(C.get(i)<A.get(i))
                break;
            if(pre[C.get(i)+1]-pre[A.get(i)]<i+1)
                break;
            ans++;
        }
        return ans*3;
    }
    
}

分贝壳游戏

链接:https://ac.nowcoder.com/acm/contest/9752/C

题目描述

现在牛牛和牛妹一起出去海滩游玩,由于他们两个都不会游泳,所以他们在海滩捡了很多好看的贝壳,可是捡着捡着他们就感觉无聊了,所以他们决定拿这些贝壳玩一些游戏。

他们一共捡了n个贝壳,现在他们这n个贝壳放成一堆。然后轮流取贝壳,牛牛先取。牛牛一次能取[1,p]个贝壳,牛妹一次能取[1,q]个贝壳,能拿到最后一个贝壳的人赢

问牛牛和牛妹都足够聪明的情况下,最后谁能取得胜利

如果牛牛必胜,返回1

如果牛妹必胜,返回-1

如果没有人有必胜策略,返回0

如果p=q那就是巴什博弈,如果不等于则能取石子数大的那个人获胜,原理是永远尽量留对方能取石子数+1的倍数的石子数量

如果两方能取的数量不同,比如一个能取6一个能取7,那么6的那个人想留8的倍数给对方让对方输,但是只剩8个时,对方却可以留7这样取6的那个人永远赢不了

import java.util.*;


public class Solution {
    /**
     * 
     * @param n int整型 
     * @param p int整型 
     * @param q int整型 
     * @return int整型
     */
    public int Gameresults (int n, int p, int q) {
        // write code here
        if( p >= n )  return 1;
        if( p == q )
        {
            if( n%(p+1) == 0 )  return -1;
            else return 1;
        }
        else
        {
            if( p > q )  return 1;
            else return -1;
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值