脑筋急转弯AQA

1:你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。
你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
来源:leetcode
思路:假设石头数量为n,每次可以拿的石头数为1-m,前提是n一定要大于m,否则第一个人直接就获胜了
那么只要你在倒数第二次拿石头后剩下的是可以拿的最大数量加1,那么必然会获胜;也就是说,只要保证剩下的石头数能被m+1整除,且你已经拿过石头了,就一定会获胜
那么:

public static boolean canWinNim(int n,int m) {
  if(m==0)return false;
   return n%(m+1)==0?false:true;
}

获胜情况下,第一个人要拿的数量为n%(m+1)

2:初始时有 n 个灯泡关闭。 第 1 轮,你打开所有的灯泡。 第 2 轮,每两个灯泡你关闭一次。 第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭)。第 i 轮,每 i 个灯泡切换一次开关。 对于第 n 轮,你只切换最后一个灯泡的开关。 找出 n 轮后有多少个亮着的灯泡
来源:leetcode
思路:经过一一测试计算,结果超时了,仔细一看有规律,给n开方就行了;

//推理逻辑
//             boolean arr[]=new boolean[n];
//             if(n==1||n==2){
//                 return 1;
//             }
//             for (int i = 0; i <arr.length ; i++) {
//                 if(i%2==0)arr[i]=true;
//             }
//             int i=3;
//             while (i<=n){
//                 for (int j = i-1; j <arr.length ; j+=i) {
//                     arr[j]=arr[j]==false?true:false;
//                 }
//                 i++;
//             }
//             for (int j = 0; j <arr.length ; j++) {
//                 if(arr[j])num++;
//             }
//             return num;

//具体实现

int num = 1;
while (n >= num * num) {
    num++;
}
return num - 1;

3:三枚石子放置在数轴上,位置分别为 a,b,c。
每一回合,我们假设这三枚石子当前分别位于位置 x, y, z 且 x < y < z。从位置 x 或者是位置 z 拿起一枚石子,并将该石子移动到某一整数位置 k 处,其中 x < k < z 且 k != y。
当你无法进行任何移动时,即,这些石子的位置连续时,游戏结束。
要使游戏结束,你可以执行的最小和最大移动次数分别是多少? 以长度为 2 的数组形式返回答案:answer = [minimum_moves, maximum_moves]
来源:leetcode
思路:先排序,两边数字到中间隔了几个数,最大移动次数就是几,最小次数的最大值为2,即两边到中间的间隔均大于2,其次是1,即只有一边的间隔大于2,最小是0,即三数连续;
实现:

 public int[] numMovesStones(int a, int b, int c) {         
       int arr[]=new int [2];int m=1,n=1;        
       int brr[]={a,b,c};        
       Arrays.sort(brr);         
       if(brr[1]-brr[0]-1==0&&brr[2]-brr[1]-1==0)arr[0]=0;         
       else if(brr[1]-brr[0]-1==0||brr[2]-brr[1]-1==0||brr[1]-brr[0]-1==1||brr[2]-brr[1]-1==1)arr[0]=1;         
       else arr[0]=2;        
      arr[1]=brr[1]-brr[0]-1+brr[2]-brr[1]-1;       
       return arr;  
 }

4:在一个由 ‘L’ , ‘R’ 和 ‘X’ 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。
来源:leetcode
思路:将X看成空格,要从start到end要达成三个条件,
1》去掉所有X,start=end
2》start的R左边的X数量小于等于end的R左边的
3》Start的L左边的X数量大于end的L左边的
实现:

public static boolean canTransform(String start, String end) {
    int l=start.length();
    int i=0,j=0;
    while (i<l&&j<l){
        while (start.charAt(i)=='X'&&i<l-1)++i;
        while (end.charAt(j)=='X'&&j<l-1)++j;
        if (start.charAt(i)!=end.charAt(j)) return false;
        else if (start.charAt(i)=='L' && i<j) return false;
        else if (start.charAt(i)=='R' && i>j)return false;
        i++;
        j++;
    }

    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值