2018腾讯笔试题

1.小Q定义了一种数列称为翻转数列:
给定整数n和m, 满足n能被2m整除。对于一串连续递增整数数列1, 2, 3, 4..., 每隔m个符号翻转一次, 最初符号为'-';。
例如n = 8, m = 2, 数列就是: -1, -2, +3, +4, -5, -6, +7, +8.
而n = 4, m = 1, 数列就是: -1, +2, -3, + 4.
小Q现在希望你能帮他算算前n项和为多少。

import java.util.Scanner;
public class Main{
   public static void main(String[] args){
       Scanner s = new Scanner(System.in);
       int n = s.nextInt();
       int m = s.nextInt();
       Long sum = 0L;
       int flag = 1;
       for(int i = 1; i <= n; i++){
           if(flag <= m){
               sum = sum - (int)i;
           }
           else if(flag > m && flag <= 2*m){
               sum = sum + (int)i;
           }
           if(flag == 2*m){
               flag = 0;
           }
           flag = flag + 1;
            
       }
       System.out.println(sum);
        
   }
}
过了90%的case,数字过大会超时=。=
看别人的正确答案都是直接算 m*n/2;这原来是数学题么!

 

2.牛牛和羊羊正在玩一个纸牌游戏。这个游戏一共有n张纸牌, 第i张纸牌上写着数字ai。
牛牛和羊羊轮流抽牌, 牛牛先抽, 每次抽牌他们可以从纸牌堆中任意选择一张抽出, 直到纸牌被抽完。
他们的得分等于他们抽到的纸牌数字总和。
现在假设牛牛和羊羊都采用最优策略, 请你计算出游戏结束后牛牛得分减去羊羊得分等于多少。

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int a[]  = new int[n];
        for(int i = 0; i < n; i++){
            a[i] = sc.nextInt();
        }
        Arrays.sort(a);
        Long sum = 0L;
        int jishu = 0;
        for(int i = n-1; i >= 0; i--){
            if(jishu == 0){
                sum = sum + (int)a[i];
                jishu = -1;
            }
            else{
                sum = sum - (int)a[i];
                jishu = 0;
            }
        }
        System.out.println(sum);
       
    }
}

 

3.小Q的父母要出差N天,走之前给小Q留下了M块巧克力。小Q决定每天吃的巧克力数量不少于前一天吃的一半,但是他又不想在父母回来之前的某一天没有巧克力吃,请问他第一天最多能吃多少块巧克力

import java.util.Scanner;
public class Main{
   
   //算第一天吃f块时,吃n天需要总量是多少。
    public static int minCho(int f, int n){
        int minCho = 0;
        for(int i = 0; i < n; i++){
            
            if(f >= 2){
                minCho = minCho + f;
                if(f%2 == 0){
                    f=f/2;
                }
                else{
                    f=f/2 + 1;
                }
            }
            else{
                minCho = minCho + 1;
            }
        }
        return minCho;
    }
    
    public static void main(String[] args){
       Scanner s = new Scanner(System.in);
       int n = s.nextInt();
       int m = s.nextInt();
       int i = m;
       for(; i >= 1; i--){
           if(minCho(i, n) <= m){
               break;
           }
       }
       System.out.println(i);
   }
}

 

4.小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌,现在小Q想用这些歌组成一个总长度正好为K的歌单,每首歌最多只能在歌单中出现一次,在不考虑歌单内歌曲的先后顺序的情况下,请问有多少种组成歌单的方法。

首先一个数学知识:C(m,n)=m!/[(m-n)!n!]

 

- -虽然做出来了不过只能过60%的case,数字有点大,用的最暴力的办法。。。先穷举出所有排列,然后用C(m,n)求出结果,不知道为什么算出来一些测试用例和标准答案不一样。。。

import java.util.*;
import java.math.BigInteger;
public class Main{
    public static final int ASD = 1000000007;
     
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int k=sc.nextInt();
        int a=sc.nextInt();
        int x=sc.nextInt();
        int b=sc.nextInt();
        int y=sc.nextInt();
        
        //k=17;a=5;x=79;b=4;y=66;
        k=205;a=1;x=92;b=4;y=92;

        //3615040
        
        
        sc.close();
        BigInteger sum = BigInteger.valueOf(0);
        for(int i = 0; i < x; i++){
            for(int j = 0; j < y; j++){
                int n = a * i + b * j; 
                if(n == k){
                    //System.out.println(i + " " + j);
                    sum = sum.add(c(x,1).multiply(c(y,j)));
                }
            }
        }
        sum = sum.mod(BigInteger.valueOf(1000000007));
        System.out.println(sum);
    }
    
    public static BigInteger c(int n, int m){
        BigInteger nm1 = BigInteger.valueOf(1);
        BigInteger m1 = BigInteger.valueOf(1);
        BigInteger n1 = BigInteger.valueOf(1);
        for(int i = n; i > 0; i--){
            n1 = n1.multiply(BigInteger.valueOf(i));
        }
        for(int i = n-m; i > 0; i--){
             nm1 = nm1.multiply(BigInteger.valueOf(i));
        }
        for(int i = m; i > 0; i--){
             m1 = m1.multiply(BigInteger.valueOf(i));
        }
        //System.out.println(n1 + " " + m1 + " " + nm1);
        BigInteger re = n1.divide(m1).divide(nm1);
        //System.out.println("re=" + re);
        return re;
    }
}

 

 

抄了一份别人的

import java.util.*;
 
public class Main{
    public static final int ASD = 1000000007;
     
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int k=sc.nextInt();
        int a=sc.nextInt(), x=sc.nextInt();
        int b=sc.nextInt(), y=sc.nextInt();
        int[] dp = new int[k+1];
        dp[0] = 1;
        for(int i=0; i<x ; i++){
            for(int j=k; j>=a; j--){
                dp[j] = (dp[j] + dp[j-a]) % ASD;
            }
        }
         
        for(int i=0; i<y ; i++){
            for(int j=k; j>=b; j--){
                dp[j] = (dp[j] + dp[j-b]) % ASD;
            }
        }
         
        System.out.println(dp[k]);
        sc.close();
    }
}

 

 

采用了背包问题的解决思路。

之前没接触过,专门研究一下;

 

posted @ 2019-08-19 11:54  不咬人的兔子  阅读(253)  评论(0编辑  收藏  举报