腾讯不招java_java - 算法 - 腾讯2018春招

输入描述:

输入包括两个整数n和m(2 <= n <= 109, 1 <= m), 并且满足n能被2m整除。

输出描述:

输出一个整数, 表示前n项和。

输入例子1:

8 2

输出例子1:

8

packagetx;importjava.math.BigInteger;import java.util.*;public classq1{public static voidmain(String[] args){

Scanner s= newScanner(System.in);

String str=s.nextLine();

String[] strArr= str.split(" ");

BigInteger n= new BigInteger(strArr[0]);

BigInteger m= new BigInteger(strArr[1]);

BigInteger sum= m.multiply(n).divide(new BigInteger("2"));

System.out.println(sum);

}

}

题本身不难- - 用初中数学只是就能得出结果是 m*n/2

主要是用到了bigInteger处理大数字。

2.

牛牛和羊羊正在玩一个纸牌游戏。这个游戏一共有n张纸牌, 第i张纸牌上写着数字ai。

牛牛和羊羊轮流抽牌, 牛牛先抽, 每次抽牌他们可以从纸牌堆中任意选择一张抽出, 直到纸牌被抽完。

他们的得分等于他们抽到的纸牌数字总和。

现在假设牛牛和羊羊都采用最优策略, 请你计算出游戏结束后牛牛得分减去羊羊得分等于多少。

输入描述:

输入包括两行。

第一行包括一个正整数n(1 <= n <= 105),表示纸牌的数量。

第二行包括n个正整数ai(1 <= ai <= 109),表示每张纸牌上的数字。

输出描述:

输出一个整数, 表示游戏结束后牛牛得分减去羊羊得分等于多少。

输入例子1:

3

2 7 4

输出例子1:

5

packagetx;import java.util.*;public classq2{public static voidmain(String[] args){

Scanner s= newScanner(System.in);

String str1=s.nextLine();int num =Integer.parseInt(str1);

String str2=s.nextLine();

String[] strArr= str2.split(" ");int[] iArr = new int[num];for(int i = 0; i < num; i++) {

iArr[i]=Integer.parseInt(strArr[i]);

}

sort(iArr,0, num - 1);int sum = 0;for(int i = 0; i < num; i++){if(i % 2 == 0){

sum= sum +iArr[i];

}else{

sum= sum -iArr[i];

}//System.out.println(iArr[i]);

}

System.out.println(sum);

}public static void sort( int[] iArr, int start, int end){ //冒泡排序会超时,采用快速排序

if(start >end){return;

}int base =start;int low =start;int high =end;while(low =iArr[base]){

low++;

}while(high > start && iArr[high] <=iArr[base]){

high--;

}if(low >high){break;

}else{int temp =iArr[high];

iArr[high]=iArr[low];

iArr[low]=temp;

}

}int temp =iArr[high];

iArr[high]=iArr[base];

iArr[base]=temp;

sort(iArr, start, high- 1);

sort(iArr, high+ 1, end);

}

}

考察了排序,先排序后遍历做加减法就行。

而且由于有运行时间限制,所以用快速排序,冒泡排序等时间复杂度是O²的会超时。

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

输入描述:

每个输入包含一个测试用例。

每个测试用例的第一行包含两个正整数,表示父母出差的天数N(N<=50000)和巧克力的数量M(N<=M<=100000)。

输出描述:

输出一个数表示小Q第一天最多能吃多少块巧克力。

输入例子1:

3 7

输出例子1:

4

packagetx;import java.util.*;public classq3{public static voidmain(String[] args){

Scanner s= newScanner(System.in);int n = s.nextInt(); //天数

int m = s.nextInt(); //巧克力数量//二分法查找第一天的最大巧克力数量

int start = 0;int end =m;while(start

start = sweetNum + 1;

}else{

end=sweetNum;

}

}if(n == 1) { //n = 1时二分查找会有问题,所以单独拿出来。

System.out.println(m);

}else{

System.out.println(end- 1);

}

}public static boolean isEnough(int n , int m, int sweetNum){ //判断 sweet在n天内能否够吃

for(int i = 0; i < n ; i++) {

m= m -sweetNum;

sweetNum= (int)Math.ceil(sweetNum * 1.0 / 2);

}if(m >= 0){return true;

}else{return false;

}

}

}

本质:从m个顺序排列的数字中(1 - m)寻找符合要求的最大值。

用遍历会超时,用二分查找,寻找符合要求的最大值。

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

输入描述:

每个输入包含一个测试用例。

每个测试用例的第一行包含一个整数,表示歌单的总长度K(1<=K<=1000)。

接下来的一行包含四个正整数,分别表示歌的第一种长度A(A<=10)和数量X(X<=100)以及歌的第二种长度B(B<=10)和数量Y(Y<=100)。保证A不等于B。

输出描述:

输出一个整数,表示组成歌单的方法取模。因为答案可能会很大,输出对1000000007取模的结果。

输入例子1:

5

2 3 3 3

输出例子1:

9

packagetx;importjava.math.BigInteger;import java.util.*;public classq4{public static voidmain(String[] args){

Scanner s= newScanner(System.in);int k = Integer.parseInt(s.nextLine()); //天数

String str = s.nextLine(); //巧克力数量

String[] steArr = str.split(" ");int a = Integer.parseInt(steArr[0]); //长度

int x = Integer.parseInt(steArr[1]); //数量

int b = Integer.parseInt(steArr[2]);int y = Integer.parseInt(steArr[3]);//求出两种歌的个数有多少种组合。

ArrayList aa = newArrayList();

ArrayList bb = newArrayList();for(int i = 0; i <= x; i++){int r = k - a *i;if(r % b == 0 && r/b <=y){

aa.add(i);

bb.add(r/b);

}

}

BigInteger bi= new BigInteger("0");for(int i = 0; i < aa.size(); i++){

BigInteger temp=getC(aa.get(i), x);

temp=temp.multiply(getC(bb.get(i), y));

bi=bi.add(temp);

}

bi= bi.mod(new BigInteger("1000000007"));

System.out.println(bi);

}public static BigInteger getC(int x, inty){if (x == 0) {return new BigInteger("1");

}

BigInteger bi= new BigInteger("1");for(int i = 1; i <= y; i++){

bi= bi.multiply(new BigInteger("" +i));

}for(int i = 1; i <= x; i++){

bi= bi.divide(new BigInteger("" +i));

}for(int i = 1; i <= ( y - x); i++){

bi= bi.divide(new BigInteger("" +i));

}

bi= bi.mod(new BigInteger("1000000007"));returnbi;

}

}

我是先求出x 和 y的数量上的组合种类,然后对每种情况分别求x和y的 C(n,m)的乘积, 然后结果相加

比如例题中只有一种情况:x取1个,y取1个

c(1,3) * c(1,3) = 9

x从3个中取1个,y也是从3个中取1个,总共有9中不同取法。

c(n,m)   : 不考虑顺序的情况下,从m个物品中抽出n个有多少种排列组合

数学公式:C(n,m)=n! / ( m! * (n-m)! )

还有2个- -明天再做。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值