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(); } }
采用了背包问题的解决思路。
之前没接触过,专门研究一下;