“字節跳動-文遠知行杯”廣東工業大學第十四屆程序設計競賽

之前發的博客一直都是水貼,被隊友一波吐槽之後決定還是發一些不太水的吧。剛好昨天有這場比賽,聽外校的師兄說,這場比賽的難度和大公司面試和筆試的難度沒差多少。所以順便就一起發一下這場比賽的貼吧。

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題,其實我當時是推出公式和草稿寫好矩陣了,但是由於本人水平有限,不怎麼會寫矩陣的快速冪,而且當時在比賽,總不能百度套模板,就懂的,現在在補。

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