“字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛

之前发的博客一直都是水贴,被队友一波吐槽之后决定还是发一些不太水的吧。刚好昨天有这场比赛,听外校的师兄说,这场比赛的难度和大公司面试和笔试的难度没差多少。所以顺便就一起发一下这场比赛的贴吧。

A题:hzy 和zsl 的生存挑战

Problem Description
zsl 和hzy 来到了臭臭城堡,打算挑战臭臭城堡的大魔王hyz,大魔王hyz设置了这样的一个挑战:

  1. zsl 和hzy两个人各自来到一间密室,期间两人无法以任何形式交流
  2. 大魔王hyz会随机在两个人的脑海里各发送一个数字,0或者是1
  3. zsl 和 hzy 需要猜对这俩个数字才算通关,但是大魔王hyz觉得人生不能过于无敌,因此降低难度,只要两个人中有一个人答对就算是通关

现在大魔王hyz 给出的数字可能的情况有 00, 01, 10, 11 四种,请按上述枚举的顺序,计算所有情况下zsl 和hzy 通关的机率。(假设zsl 和 hzy 两个人都足够机智,能够选择出最优决策)

Input
(空)

Output
输出四个答案,每个答案后面跟随一个换行符并且保留两位小数位,分别对应00,01,10,11的情况下,zsl和hzy通关的机率

Sample Input
(空)

Sample Output
1.00
0.00
0.50
0.55 (输出仅做格式参考,不保证正确性)

这题有点坑吧,而且我也太马虎了,题目没看清,原本以为是条件概率,想了老半天,最后是看到题目说假设zsl 和 hzy 两个人都足够机智,能够选择出最优决策,那就是不是意味着无论大魔王选什么数,他们最后都能选到正解,然后就填了1.00,结果就过了。

还是让我们看看正确的分析吧

一定能够通关。其中一种策略为:(第一位数字为 zsl 的数字,第二位为 hzy 的数字)
如果 zsl 的数字是 1,就猜测 10, 是 0,则猜测 01
如果 hzy 的数字是 1,就猜测 11, 是 0,则猜测 00
00:zsl 猜测 01, hzy 猜测 00
01:zsl 猜测 01,hzy 猜测 11
10:zsl 猜测 10,hzy 猜测 00
11:zsl 猜测 10,hzy 猜测 00

AC代码:

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Scanner;
public class Main {
    static StreamTokenizer sc=new StreamTokenizer(new BufferedInputStream(System.in));
    static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
    public static int nextInt() throws IOException {
        sc.nextToken();
        return (int) sc.nval;
    }
    public static double nextDouble() throws IOException {
        sc.nextToken();
        return (double) sc.nval;
    }
    public static long nextLong() throws IOException {
        sc.nextToken();
        return (long) sc.nval;
    }
    public static String next() throws IOException {
        sc.nextToken();
        return (String) sc.sval;
    }
    public static void main(String[] args) throws IOException{
        double a=1;
        System.out.println(String.format("%.2f",a));
        System.out.println(String.format("%.2f",a));
        System.out.println(String.format("%.2f",a));
        System.out.println(String.format("%.2f",a));
    }
}

B题:人类史上最大最好的希望事件

Problem Description
作为CNCS的半壁江山,狗哥常常在宇宙中心邵阳眺望黄浦江,夜晚的星空总是迷人,有时候还能见到彗星滑落。

狗哥是幸运的,他在两秒钟内看到了十七颗彗星划过天际,作为打ACM的学者,自然不会有「稳定-1」情况。他开始研究彗星运动的轨迹,发现他们都遵照斐波那契螺旋线在运动着。

尤里卡!狗哥觉得这就是找寻「生命,宇宙和一切的终极答案」的精要所在,但是怎么表示呢?狗哥觉得求取斐波那契螺旋线经过的一个个方格的面积之和就是公式的表现。

例如下图,螺旋线每划过一个方格,都转过了四分之一圈。如果我们以四分之一圈为单位,那么我们用类似带分数的形式表示螺旋线转动的起点和终点。例如,0+0 到 0 + 1 意即从第一个方格转到第二个方格,划过了前两个方格,他们的面积之和为2(1+1)。同理,0+0 到 1+0 划过了前五个方格,他们的面积之和为40(1+1+4+9+25)。

在这里插入图片描述

但是聪明的狗哥需要一个程序去获得指定范围内的螺旋线面积之和,狗哥给了你一首「希望之花」的时间,而他需要利用这个时间去打出四暗刻单骑。如果你能完成这个程序,狗哥会封你为格拉摩根伯爵

Input
不定组数据。

首先输入一个整数Q,代表狗哥询问次数。

接下来Q行,每行四个整数a,b,c,d,代表狗哥想求 a+b 到 c+d 之间的螺旋线面积之和。

1<= Q <= 10000

0<= a,c <= 10000

0 <= b,d <= 3

结果对192600817取模。

Output
一个数字,表示螺旋线面积之和。

Sample Input
4
0 0 0 1
0 0 1 0
1 2 2 1
1 1 0 3
4
0 0 0 1
0 0 1 0
1 2 2 1
1 1 0 3

Sample Output
2
40
4791
98
2
40
4791
98

这题是一道令人很忧伤的题目,因为做A题和H题花了太久时间,而且当时看到第一眼以为是很难的数学题,就放弃了,直到最后,这题好像是最后半个小时才开题的,思路一下子就上来了,后来因为写程序跑的时候,输入输出出了问题,卡了我二十来分钟,最后时间到了,还是没来得及提交,后来慢慢做了二十来分钟,提交一看,过了,23333333。

看一下正确分析(虽然我没用上)

先读懂题目
我们有一个斐波那契数列 1 1 2 3 5 8 13 … 题目需要我们求所谓的面积之和
面积即为 1 1 4 9 25 64 169… 然后一个简单的前缀和,计算面积和. 然而斐波那契数列的平方和为
f[1]*f[1]+f[2]*f[2]+…+f[n]*f[n]=f[n]*f[n+1]

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Scanner;
public class Main {
    public static long []num=new long[100005];
    public static long []sum=new long[100005];
    private static void init() {
        // TODO Auto-generated method stub
        num[0]=1;num[1]=1;
        sum[1]=1;sum[2]=2;
        for(int i=2;i<100004;i++) {
            num[i]=num[i-1]+num[i-2];
            num[i]%=192600817;
            sum[i+1]=((num[i]*num[i])%192600817+sum[i])%192600817;
        }
    }
    public static void main(String[] args) throws IOException{
        init();
        Scanner sc=new Scanner(new BufferedInputStream(System.in));
        while(sc.hasNext()) {
            int q=sc.nextInt();
            while(q>0) {
                int a=sc.nextInt();
                int b=sc.nextInt();
                int c=sc.nextInt();
                int d=sc.nextInt();
                int x=a*4+b;
                int y=c*4+d;
                System.out.println((sum[Math.max(y,x)+1]-sum[Math.min(x,y)]+192600817)%192600817);
                q--;
            }
        }
        sc.close();
    }
}

C题:超级无敌简单题

Problem Description
通常来说,题面短的题目一般都比较难,所以我要把题面写得很长很长。
通常来说,题面短的题目一般都比较难,所以我要把题面写得很长很长。
通常来说,题面短的题目一般都比较难,所以我要把题面写得很长很长。
鸽子数字由以下过程定义:从任何正整数开始,将数字替换为其各个数位的平方和,并重复该过程,直到该数字等于1。如果不能,则这个数字不是鸽子数。
例如7是鸽子数,因为7->49->97->130->10->1。(77=49,44+99=97,99+7*7=130…如此类推)
显然1是第一个鸽子数。
有Q个询问,每个询问给出一个数k,你需要输出第k个鸽子数。

Input
第一行一个Q,代表询问的个数(Q<=100000)
接下来Q行,每行一个数字k(k<150000)

Output
每行输出一个数,代表第k个鸽子数

Sample Input
2
1
2

Sample Output
1
7

其实 这个鸽子数应该叫开心数吧,之前在LeetCode入门的时候有刷过类似题,因为我做的数学类笔记有出现,其实就暴力打表,然后打够150005个开心数就行,刚开始不敢这么暴力的,后来想不到该怎么优化了,就直接敲了,然后A了。

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.HashSet;
public class Main {
    static StreamTokenizer sc=new StreamTokenizer(new BufferedInputStream(System.in));
    static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
    public static int nextInt() throws IOException {
        sc.nextToken();
        return (int) sc.nval;
    }
    public static long []num=new long [150005];
    public static void init() {
        num[0]=1;
        int ind=1;int i=2;
        while(ind<num.length) {
            if(isHappy(i))
                num[ind++]=i;
            i++;
        }
    }
    public static boolean isHappy(int n) {
        HashSet<Integer> hs = new HashSet<>();
        hs.add(n);
        while(n!=1){
            int sum =Sum(n);
            if(hs.contains(sum))
                return false;
            hs.add(sum);
            n=sum;
        }
        return true;
    }
    private static int Sum(int n){
        int sum=0;
        while(n!=0){
            int num=n%10;
            sum+=(num)*(num);
            n/=10;
        }
        return sum;
    }
    public static void main(String[] args) throws IOException{
        init();
        int q=nextInt();
        while(q>0) {
            int k=nextInt();
            System.out.println(num[k-1]);
            q--;
        }
        
    }
}

D题,E题,F题

由于本人不会,就不发出来了,我还是个菜鸡,大家别介意哈

G题:简单数学题

Problem Description
已知

F(n)=∑i=1n(i×∑j=inCij)

求 F(n) mod 1000000007

Input
多组输入,每组输入占一行,包含一个整数n(1 <= n <= 1e18)。
数据不超过300000组。

Output
对于每组输入,输出一行,包括一个数代表答案。

Sample Input
5
100

Sample Output
129
660756544

这题其实我还没A,只是发出来,看看有没有大佬愿意指点一下,还有就是网上还有一篇这题C++相关的AC代码,但是我提交了一下,还是显示超时。

菜鸡本人未AC代码:(报超时了,后来用欧拉降幂也不行)

import java.io.BufferedInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) throws IOException{
    	Scanner sc=new Scanner(new BufferedInputStream(System.in));
    	BigInteger tmp=BigInteger.valueOf(2);
    	BigInteger mod=BigInteger.valueOf(1000000007);
    	while(sc.hasNext()) {
    		BigInteger n=sc.nextBigInteger();
    		n=n.mod(mod);
    		System.out.println((n.subtract(BigInteger.ONE)).multiply(tmp
    				.modPow(n.mod(mod), mod)).add(BigInteger.ONE).mod(mod));
    	}
	    sc.close();
    }
}

给出该题的分析先

在这里插入图片描述

H题:Zyb 的面试

Problem Description
今天zyb参加一场面试,面试官听说zyb是ACMer之后立马抛出了一道算法题给zyb:
有一个序列,是1到n的一种排列,排列的顺序是字典序小的在前,那么第k个数字是什么?
例如n=15,k=7, 排列顺序为1, 10, 11, 12, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8, 9;那么第7个数字就是15.
那么,如果你处在zyb的场景下,你能解决这个问题吗?

Input
T组样例(T<=100)
两个整数n和k(1<=n<=1e6,1<=k<=n),n和k代表的含义如上文

Output
输出1-n之中字典序第k小的数字

Sample Input
1
15 7

Sample Output
15

这题大概是我花时最久的一道了,本来是想着重写一下排序方法,然后用比较字符串的CompareTo方法将数值重新排序的,结果报了超时,后来想了半天,想了一个挺暴力的方法,就是比如n是1-999,那么肯定以1开头的有111个,那么你求第112个的时候,我只需要减去111个,就知道我要求的数了,以此类型,1-99以1开头的有11,写了之后,过了。
后来听说这是今日头条秋招的真题,哇,不愧是大公司,网上也有该题的解法,是字典树的形式。找了一下,发几个觉得写得不错的。
解法1:(https://blog.csdn.net/Hay54/article/details/82014966)
解法2:(https://blog.csdn.net/Hay54/article/details/82014966)

下面这个我看代码觉得思路和我的差不多,而且代码写得是真的比我好看,还有比较,大家可以去看看,我觉得会更容易消化和理解这道题

https://blog.csdn.net/caoxiaohong1005/article/details/78681450

分析:
在这里插入图片描述
在这里插入图片描述

后面的J题,其实我当时是推出公式和草稿写好矩阵了,但是由于本人水平有限,不怎么会写矩阵的快速幂,而且当时在比赛,总不能百度套模板,就懂的,现在在补。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章