牛牛爱喝酒
链接: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;
}
}
}