山東大學(威海)程序設計競賽2020新星賽(線上模擬賽)題解

7-1 factorial

In many applications very large integers numbers are required. Some of these applications are using keys for secure transmission of data, encryption, etc. In this problem you are given a number, you have to determine the number of digits in the factorial of the number.

Input:

Input consists of several lines of integer numbers. The first line contains an integer T, which is the number of cases to be tested, followed by T lines, one integer 1 ≤ n ≤ 10000000 on each line.

1≤T≤10

Output:

The output contains the number of digits in the factorial of the integers appearing in the input.

Sample Input:

2
10
20

Sample Output:

7
19

Solution:

詢問一個數的階乘結果的位數。

如果硬算,當 n 超過 12 臨時變量就會爆 int,即使用 int_128 在 n 達到 100 時也頂不住,更不用說 1e7 的上限。

如果用高精度(見 7-6)運算,在這種數據量下必超時。

不難想到對於一個數 n,它的位數 dig(n) = [log10(n)] + 1。

因此 dig(n!) = [log10(1 * 2 * 3 * ... * n)] + 1 = [log10(1) + log10(2) + ... + log10(n)] + 1。  

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        double sum = 0;
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++)
            sum += log10(i);
        cout << (int)sum + 1 << endl;
    }
    return 0;
}

7-2 exam

The final exam is over. In order to give rewards, the teacher should rank the students in the class.

There are N students in the class. This semester, they have learned K courses.

The student number of the i-th student is Xi, and his score of the j-th course is expressed as Aij.

The ranking rules are as follows:

If the scores of two students are different, the first course with different scores will be the basis for ranking, and the one with higher scores will come first.

If the scores of the two students are identical, the one with the smaller student number will come first.

Input:

The first line contains N, K (N≤1000,K≤10).

In the following N lines, the i-th line contains K+1 integers X​i​​ A​i1​​ A​i2​​ A​i3​​ … A​ik​​. (X​i​​<100000,A​ij​​<100000)

Guarantee student number is different.

Output:

A line contains n integers, which are the student numbers from the first to the last, separated by spaces.

There should be a space after the last number

Sample Input:

4 3
1 1 2 3
2 1 3 3
3 2 2 2
4 2 2 3

Sample Output:

4 3 2 1 

Solution:

細心讀題並觀察樣例,排序要求類似字符串字典序。

#include <bits/stdc++.h>
using namespace std;

int n, k;
using p = pair<vector<int>, int>;

bool cmp(const p& a, const p& b)
{
    for (int i = 0; i < k; i++)
        if (a.first[i] != b.first[i])
            return a.first[i] > b.first[i];
    return a.second < b.second;
}

int main()
{
    cin >> n >> k;
    vector<p> vec;
    for (int i = 0; i < n; i++)
    {
        int id;
        cin >> id;
        vector<int> score(k);
        for (int j = 0; j < k; j++) cin >> score[j];
        vec.push_back(p(score, id));
    }
    sort(vec.begin(), vec.end(), cmp);
    for (int i = 0; i < n; i++) cout << vec[i].second << " ";
    return 0;
}

7-3 stack

Xiaoming is learning stack. Stack is a last in, first out data structure. There are only two operations: adding an element to the end of the stack and taking out the end element. Now Xiaoming asks you to help him simulate the operation of the stack.

Input:

The first line contains an integer n indicating how many operations there are. (N≤100000)

Next N lines, two integers A and B per line. A = 1 means to add B to the tail of the stack, A = 2 means to take out the tail element of B times. (B<100000)

The stack is initially empty. Ensure that elements are not removed from the empty stack.

Output:

The first line, an integer m, indicates how many elements are left in the stack.

The second line, m integers, lists the m elements from the beginning to the end of the stack, separated by spaces.

Sample Input:

5
1 2
1 4
2 1
1 3
1 5

Sample Output:

3
2 3 5 

Solution:

模擬棧的 push 和 pop 操作,再從棧底逐個輸出。可用雙端隊列代替。

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int t;
    cin >> t;
    deque<int> q;
    while (t--)
    {
        int n, k;
        cin >> n >> k;
        if (n == 1) q.push_back(k);
        else while (k--) q.pop_back();
    }
    cout << q.size() << endl;
    while (!q.empty())
    {
        cout << q.front() << " ";
        q.pop_front();
    }
    return 0;
}

7-4 Hateful fat

LCY lost his pen when he was studying, which is really a bad situation, because his eyes have been blocked by his fat. So can you tell him the positional relationship between him and the pencil?

圖片 1.png

For given three points p0,p1,p2,

print " COUNTER_CLOCKWISE” if p0,p1,p2 make a counterclockwise turn (1)

print " CLOCKWISE” if p0,p1,p2 make a clockwise turn (2),

print " ONLINE_BACK” if p2 is on a line p2,p0,p1 in this order (3),

print " ONLINE_FRONT “if p2 is on a line p0,p1,p2 in this order (4),

print " ON_SEGMENT” if p2 is on a segment p0p1(5).

Input:

In the first line, integer coordinates of p0 and p1 are given.

The next line gives an integer q, which represents the number of queries.

Then, q queries are given for integer coordinates of p2.

Output:

For each query, print the above mentioned status.

Sample Input:

0 0 2 0
3
-1 1
-1 -1
2 0

Sample Output:

COUNTER_CLOCKWISE
CLOCKWISE
ON_SEGMENT

Solution:

基礎計算幾何,判斷兩個向量之間的關係。可利用點積和叉積性質分類討論解決。

#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> p;

int dot(const p& a, const p& b) { return a.first * b.first + a.second * b.second; }

int cross(const p& a, const p& b) { return a.first * b.second - a.second * b.first; }

p vec(const p& x, const p& y) { return p(y.first - x.first, y.second - x.second); }

int main()
{
    int x0, y0, x1, y1, q;
    cin >> x0 >> y0 >> x1 >> y1 >> q;
    p p0(x0, y0);
    p p1(x1, y1);
    while (q--)
    {
        int x2, y2;
        cin >> x2 >> y2;
        p p2(x2, y2);
        p a = vec(p0, p1);
        p b = vec(p0, p2);
        int cro = cross(a, b);
        if (cro > 0) cout << "COUNTER_CLOCKWISE" << endl;
        else if (cro < 0) cout << "CLOCKWISE" << endl;
        else
        {
            int dt = dot(a, b);
            if (dt < 0) cout << "ONLINE_BACK" << endl;
            else if ((double)b.first / a.first > 1.0) cout << "ONLINE_FRONT" << endl;
            else cout << "ON_SEGMENT" << endl;
        }
    }
    return 0;
}

7-5 prime

Xiaoming is learning prime number, which is a integer greater than 1 and can only be divided by 1 and itself. Xiao Ming has learned how to judge whether a number is prime. Now, he wants to know how many prime numbers are in [1, N].

Input:

An integer N.(N<=10000000)

Output:

An integer represents how many prime numbers are in [1, N].

Sample Input:

10

Sample Output:

4

Solution:

詢問 1e7 上限範圍內的素數個數。

單獨判斷一個數 n 是否爲素數複雜度爲 O(√n) ,此題數據量下若逐個判斷再計數顯然會超時。

數論初步:素數篩法

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e7 + 10;
int n, cnt, prime[maxn];
bool vis[maxn];

int main()
{
    cin >> n;
    for (int i = 2; i <= n; i++) // 歐拉篩 O(n)
    {
        if (!vis[i]) prime[cnt++] = i;
        for (int j = 0; j < cnt; j++)
        {
            if (i * prime[j] > n) break;
            vis[i * prime[j]] = true;
            if (i % prime[j] == 0) break;
        }
    }
    cout << cnt;
    return 0;
}

7-6 lcy‘s weight

During the holiday, LCY has been eating snacks, but sometimes he also exercises, so his weight has been changing. At the same time, LCY is an excellent college student, so he records the change of his weight the day before every day. But n days later, he found that he could not know how heavy he was now, but he could remember his weight on the first day as M. So LCY found smart you. I hope you can help him calculate his weight now, so can you help him?

Input:

The first line gives two integers, N and M, representing the days lcy experienced and the weight of the first day.(n≤10​4​​,m≤10​10000​​)

Then n lines followed.

Each line contains two integers x and y.(y≤10​10000​​)

When x equals 1, it means that LCY's current weight is y heavier than the previous day.

When x equals 2, it means that LCY's current weight is y lighter than the previous day.

When x equals 3, it means that LCY's current weight is y times heavier than the previous day.

Ensure LCY's weight is always less than 10​10000​​

Output:

Output a single line represents the weight after n days of LCY

Sample Input:

4 70
1 3
3 10
2 100
3 10000000000

Sample Output:

6300000000000

1e10000 上限的數值運算當然要用大數。

所謂高精度就是用字符串模擬加減乘除等數值運算。Java 有內置的大數類而 C++ 沒有,所以 C++ 選手需要常備模板。

#include <bits/stdc++.h>
using namespace std;

#define MAXLEN 10010
#define MAXN 9999
#define MAXSIZE 1010
#define DLEN 4

class BigNum
{
private:
    int a[MAXLEN];
    int len;
public:
    BigNum() { len = 1; memset(a,0,sizeof(a)); }
    BigNum(const int);
    BigNum(const char*);
    BigNum(const BigNum&);
    BigNum& operator =(const BigNum &);
    friend istream& operator >>(istream&, BigNum&);
    friend ostream& operator <<(ostream&, BigNum&);
    BigNum operator +(const BigNum&) const;
    BigNum operator -(const BigNum&) const;
    BigNum operator *(const BigNum&) const;
    BigNum operator /(const int&) const;
    BigNum operator ^(const int&) const;
    int operator %(const int&) const;
    bool operator >(const BigNum& T)const;
    bool operator >(const int& t)const;
    void print();
};

BigNum::BigNum(const int b)
{
    int c, d = b;
    len = 0;
    memset(a,0,sizeof(a));
    while (d > MAXN)
    {
        c = d - (d / (MAXN + 1)) * (MAXN + 1);
        d = d / (MAXN + 1);
        a[len++] = c;
    }
    a[len++] = d;
}

BigNum::BigNum(const char* s)
{
    int t, k, index, L, i;
    memset(a,0,sizeof(a));
    L = (int)strlen(s);
    len = L / DLEN;
    if (L % DLEN) len++;
    index = 0;
    for (i = L - 1; i >= 0; i -= DLEN)
    {
        t = 0;
        k = i - DLEN + 1;
        if (k < 0) k = 0;
        for (int j = k; j <= i; j++)
            t = t * 10 + s[j] - '0';
        a[index++] = t;
    }
}

BigNum::BigNum(const BigNum& T) : len(T.len)
{
    int i;
    memset(a, 0, sizeof(a));
    for (i = 0; i < len; i++) a[i] = T.a[i];
}

BigNum& BigNum::operator =(const BigNum& n)
{
    int i;
    len = n.len;
    memset(a, 0, sizeof(a));
    for (i = 0; i < len; i++) a[i]=n.a[i];
    return *this;
}

istream& operator >>(istream& in, BigNum& b)
{
    char ch[MAXSIZE * 4];
    int i = -1;
    in >> ch;
    int L = (int)strlen(ch);
    int count = 0, sum = 0;
    for (i = L - 1; i >= 0;)
    {
        sum = 0;
        int t = 1;
        for (int j = 0; j < 4 && i >= 0; j++, i--, t *= 10)
            sum += (ch[i] - '0') * t;
        b.a[count] = sum;
        count++;
    }
    b.len = count++;
    return in;
}

ostream& operator <<(ostream& out, BigNum& b)
{
    int i;
    cout << b.a[b.len - 1];
    for (i = b.len - 2; i >= 0; i--)
        printf("%04d", b.a[i]);
    return out;
}
    
BigNum BigNum::operator +(const BigNum& T) const
{
    BigNum t(*this);
    int i, big;
    big = T.len > len ? T.len : len;
    for (i = 0; i < big; i++)
    {
        t.a[i] += T.a[i];
        if (t.a[i] > MAXN)
        {
            t.a[i + 1]++;
            t.a[i] -= MAXN + 1;
        }
    }
    if (t.a[big] != 0) t.len = big + 1;
    else t.len = big;
    return t;
}

BigNum BigNum::operator -(const BigNum& T) const
{
    int i, j, big;
    bool flag;
    BigNum t1, t2;
    if (*this > T)
    {
        t1 = *this;
        t2 = T;
        flag = 0;
    }
    else
    {
        t1 = T;
        t2 = *this;
        flag = 1;
    }
    big = t1.len;
    for (i = 0; i < big; i++)
    {
        if (t1.a[i] < t2.a[i])
        {
            j = i + 1;
            while (t1.a[j] == 0) j++;
            t1.a[j--]--;
            while (j > i) t1.a[j--] += MAXN;
            t1.a[i] += MAXN + 1 - t2.a[i];
        }
        else t1.a[i] -= t2.a[i];
    }
    t1.len = big;
    while (t1.a[t1.len - 1] == 0 && t1.len > 1)
    {
        t1.len--;
        big--;
    }
    if (flag) t1.a[big - 1] = 0 - t1.a[big - 1];
    return t1;
}

BigNum BigNum::operator *(const BigNum& T)const
{
    BigNum ret;
    int i, j = 0, up;
    int temp, temp1;
    for (i = 0; i < len; i++)
    {
        up=0;
        for (j = 0; j < T.len; j++)
        {
            temp = a[i] * T.a[j] + ret.a[i + j] + up;
            if (temp > MAXN)
            {
                temp1 = temp - temp / (MAXN + 1) * (MAXN + 1);
                up = temp / (MAXN + 1);
                ret.a[i + j] = temp1;
            }
            else
            {
                up = 0;
                ret.a[i + j] = temp;
            }
        }
        if (up != 0) ret.a[i + j] = up;
    }
    ret.len = i + j;
    while (ret.a[ret.len - 1] == 0 && ret.len > 1) ret.len--;
    return ret;
}

BigNum BigNum::operator /(const int& b)const
{
    BigNum ret;
    int i, down = 0;
    for (i = len - 1; i >= 0; i--)
    {
        ret.a[i] = (a[i] + down * (MAXN + 1)) / b;
        down = a[i] + down * (MAXN + 1) - ret.a[i] * b;
    }
    ret.len = len;
    while (ret.a[ret.len - 1] == 0 && ret.len > 1) ret.len--;
    return ret;
}

int BigNum::operator %(const int& b) const
{
    int i, d = 0;
    for (i = len - 1; i >= 0; i--)
        d=((d*(MAXN+1))%b+a[i])%b;
    return d;
}

BigNum BigNum::operator ^(const int& n) const
{
    BigNum t, ret(1);
    int i;
    if (n < 0) exit(-1);
    if (n == 0) return 1;
    if (n == 1) return *this;
    int m = n;
    while (m > 1)
    {
        t = *this;
        for (i = 1; (i << 1) <= m; i <<= 1) t = t * t;
        m -= i;
        ret = ret * t;
        if (m == 1) ret = ret * (*this);
    }
    return ret;
}

bool BigNum::operator >(const BigNum& T) const
{
    int ln;
    if (len > T.len) return true;
    else if (len == T.len)
    {
        ln = len - 1;
        while (a[ln] == T.a[ln] && ln >= 0) ln--;
        if (ln >= 0 && a[ln] > T.a[ln]) return true;
        else return false;
    }
    else return false;
}

bool BigNum::operator >(const int& t) const
{
    BigNum b(t);
    return *this > b;
}

void BigNum::print()
{
    int i;
    printf("%d", a[len - 1]);
    for (i = len - 2; i >= 0; i--)
        printf("%04d", a[i]);
    printf("\n");
}
    
int main()
{
    int n;
    BigNum m;
    cin >> n >> m;
    while (n--)
    {
        int x;
        BigNum y;
        cin >> x >> y;
        if (x == 1) m = m + y;
        else if (x == 2) m = m - y;
        else m = m * y;
    }
    cout << m;
    return 0;
}

7-7 Prepare for CET-6

In order to prepare the CET-6 exam, LCY is reciting English words recently. Because he is already very clever, he can only recite n words to get full marks. He is going to memorize K words every day. But he found that if the length of the longest prefix shared by all the strings in that day is a​i​​, then he could get a​i​​ laziness value. The lazy LCY must hope that the lazier the better, so what is the maximum laziness value he can get?

For example:

The group {RAINBOW, RANK, RANDOM, RANK} has a laziness value of 2 (the longest prefix is 'RA').

The group {FIRE, FIREBALL, FIREFIGHTER} has a laziness value of 4 (the longest prefix is 'FIRE').

The group {ALLOCATION, PLATE, WORKOUT, BUNDLING} has a laziness value of 0 (the longest prefix is '').

Input:

The first line of the input gives the number of test cases, T. T test cases follow. Each test case begins with a line containing the two integers N and K. Then, N lines follow, each containing one of Pip's strings.

1≤T≤100

2≤N≤10​5​​

2≤K≤N

Each of Pip's strings contain at least one character.

Each string consists only of letters from A to Z.

K divides N.

The total number of characters in Pip's strings across all test cases is at most .

Output:

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the maximum sum of scores possible.

Sample Input:

2
2 2
KICK
START
8 2
G
G
GO
GO
GOO
GOO
GOOO
GOOO

Sample Output:

Case #1: 0
Case #2: 10

Solution:

利用 Trie 進行字符串前綴計數,樹上每位的值除以 k 求和。

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e6 + 7;
int cnt, val[maxn], trie[maxn][26];

void insert(const string& s)
{
    int u = 0;
    int len = (int)s.length();
    for (int i = 0; i < len; i++)
    {
        int id = s[i] - 'A';
        if (!trie[u][id]) trie[u][id] = ++cnt;
        val[trie[u][id]]++;
        u = trie[u][id];
    }
}

int main()
{
    int t;
    cin >> t;
    for (int i = 1; i <= t; i++)
    {
        cnt = 0;
        memset(val, 0, sizeof(val));
        memset(trie, 0, sizeof(trie));
        int n, k;
        cin >> n >> k;
        for (int j = 0; j < n; j++)
        {
            string s;
            cin >> s;
            insert(s);
        }
        int res = 0;
        for (int j = 1; j <= cnt; j++) res += val[j] / k;
        cout << "Case #" << i << ": " << res << endl;
    }
    return 0;
}

7-8 Computer Games

LCY is playing games with his computer at home. Each playing card has two attributes: A​i​​ and B​i​​, LCY and his computer take turns selecting playing cards,with LCY going first. In each turn, a player can select one card, as long as that playing card either has an A​i​​ greater than each of the all soldiers selected so far, or has a B​i​​ greater than each of the all cards selected so far.

To be precise:

let A​i​​ and B​i​​ be the values for the i-th cards, for i from 1 to N, and let S be the set of cards that have been selected so far. Then a player can select card x if and only if at least one of the following is true:

A​x​​>A​s​​ for all s in S

B​x​​>B​s​​ for all s in S

If no selection can be made, then the selection process ends and the player with more playing cards win. LCY wants to select more cards and win the game. If both players play optimally to accomplish their goals, can LCY succeed?

Input:

The first line of each case contains a positive integer N, the number of cards. N more lines follow; the i-th of these line contains two integers Ai and Bi, indicating the values of the i-th cards.(N≤4000,0≤A​i​​,B​i​​≤10000)

Output:

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is YES or NO, indicating whether LCY can guarantee that he selects more cards than computer, even if computer plays optimally to prevent this.

Sample Input:

3
3
10 2
1 10
10 3
3
10 1
10 10
1 10
3
10 2
1 10
4 9

Sample Output:

Case #1: NO
Case #2: YES
Case #3: YES

Solution:

這種博弈的精髓在於模仿。查找最內層是否成雙。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> p;

bool solve(const vector<p>& v)
{
    for (p last(1e4 + 10, 1e4 + 10), now;; last = now)
    {
        now = p(0, 0);
        for (int i = 0; i < (int)v.size(); i++)
        {
            if (v[i].first < last.first && v[i].second < last.second)
            {
                now.first = max(now.first, v[i].first);
                now.second = max(now.second, v[i].second);
            }
        }
        for (int i = 0; i < (int)v.size(); i++) if (v[i] == now) return true;
        if (now == p(0, 0)) return false;
    }
}

int main()
{
    int t;
    cin >> t;
    for (int i = 1; i <= t; i++)
    {
        int n;
        cin >> n;
        vector<p> vec(n);
        for (int i = 0; i < n; i++) cin >> vec[i].first >> vec[i].second;
        bool flag = solve(vec);
        cout << "Case #" << i << ": " << (flag ? "YES" : "NO") << endl;
    }
    return 0;
}

7-9 sort

Xiaoming is tired of asking for help. This time he wants to test you.

He gave you N integers. Please find the number with the largest M.

Input:

The first row has two numbers N, M (0<m≤n≤1000000).

The second line contains N integers that are different and are all in the interval [- 500000,500000].

Output:

Output the number of the first M in the order of large to small.

Sample Input:

5 3 
3 -35 92 213 -644

Sample Output:

213 92 3 

Solution:

簽到題

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n, m;
    cin >> n >> m;
    vector<int> v(n);
    for (int i = 0; i < n; i++) cin >> v[i];
    sort(v.begin(), v.end(), greater<int>());
    for (int i = 0; i < m; i++) cout << v[i] << " ";
    return 0;
}

7-10 lcy eats biscuits

In order to grow nine abdominal muscles, LCY began to eat all the N biscuits in his room, but LCY didn't like walking, because walking would cause his abdominal muscles to become smaller.How long does he have to run to get n biscuits. At the beginning, LCY is at (0,0)

Input:

The first line is a positive integer N.(N≤14)

Next, there are 2 real numbers in each line, representing the coordinates of the ith biscuits.(−10000≤x​i​​,y​i​​≤10000)

The distance formula between two points is√​(x​1​​−x​2​​)​2​​+(y​1​​−y​2​​)​2​​​​​

Output:

A number, representing the minimum distance to run, with 2 decimal places reserved.

Sample Input:

4
1 1
1 -1
-1 1
-1 -1

Sample Output:

7.41

Solution:

在二維座標系下,詢問從原點開始經過 n 個點的最短路程。

如果時限 1s,n 在 10 以內隨便爆搜,14 以內需要剪枝,20 以上需要狀態壓縮。

在這裏給出我的方法:首先根據座標預處理任意兩點之間的距離,然後進行狀態壓縮 DFS。

定義狀態爲到達某點時歷史訪問的點集,故對於 n 個點可用 2 ^ n 以內的二進制數表示任意一種狀態。

開一個 dp 數組存放每個狀態的最優解,需要注意的是還需要第二維:當前位置。搜索結束後遍歷每個點的最終狀態維護最優解(因爲不確定最後來到哪個點)。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<ll, ll> p;
const int inf = 0x3f3f3f3f;
const int maxn = 15;
const int maxm = 2e5;
int n;
bool vis[maxn];
double dis[maxn][maxn], dp[maxm][maxn];
p pos[maxn];

double getDis(p a, p b) { return sqrt(pow(a.first - b.first, 2) + pow(a.second - b.second, 2)); }

void dfs(int u, int sta, double tot)
{
    vis[u] = true;
    if (dp[sta][u] < tot) return; // 曾經以相同的狀態來過並且更優
    dp[sta][u] = tot;
    for (int v = 0; v <= n; v++)
    {
        if (vis[v]) continue;
        int sta_nxt = sta | (1 << (v - 1));
        dfs(v, sta_nxt, tot + dis[u][v]);
        vis[v] = false;
    }
}

int main()
{
    cin >> n;
    for (int i = 0; i < 1 << n; i++)
        for (int j = 0; j <= n; j++)
            dp[i][j] = inf;
    for (int i = 1; i <= n; i++)
        cin >> pos[i].first >> pos[i].second;
    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= n; j++)
            dis[i][j] = getDis(pos[i], pos[j]);
    dfs(0, 0, 0);
    double res = inf;
    for (int i = 1; i <= n; i++) res = min(res, dp[(1 << n) - 1][i]);
    printf("%.2lf", res);
    return 0;
}

 

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