“科林明倫杯”哈爾濱理工大學第十屆程序設計競賽(同步賽)

BCDEFHJ

B. 減成一

鏈接:https://ac.nowcoder.com/acm/contest/5758/B
來源:牛客網

題目描述 

存在n個數,每次操作可以任選一個區間使得區間內的所有數字減一。問最少多少次操作,可以讓所有數都變成1。
數據保證一定有解。

輸入描述:

輸入t,代表有t組數據。每組數據輸入n,代表有n個數。接下來一行輸入n個數,數字大小小於1e6。(t<=1000,n<1e5,∑n < 1e6)

輸出描述:

每組數據輸出一個整數代表最少需要操作的次數。

示例1

輸入

複製

1
6
1 3 5 2 7 1

輸出

複製

9

差分數組 

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

typedef long long ll;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;

template<typename T = int>
inline const T read()
{
    T x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

template<typename T>
inline void write(T x)
{
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

const int maxn = 1e5 + 10;
int a[maxn];

int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("input.txt", "r", stdin);
#endif
    int t = read();
    while (t--)
    {
        int n = read();
        ll sum = 0;
        for (int i = 1; i <= n; i++)
        {
            a[i] = read() - 1;
            sum += max(a[i] - a[i - 1], 0);
        }
        cout << sum << endl;
    }
    return 0;
}

C. 面積

鏈接:https://ac.nowcoder.com/acm/contest/5758/C
來源:牛客網

題目描述

如圖所示,正方形周圍接4個半圓,求圖形的面積

 

輸入描述:

輸入t,代表有t組數據。每組數據輸入正整數x,代表正方形的邊長。(t<100, x<1000)

輸出描述:

輸出圖形面積,並保留2位小數,其中π取3.14。

示例1

輸入

複製

1
1

輸出

複製

2.57

注意用 3.14 代替 PI

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

typedef long long ll;
typedef pair<int, int> p;
const double pi = 3.14;
const int inf = 0x3f3f3f3f;

template<typename T = int>
inline const T read()
{
    T x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

template<typename T>
inline void write(T x)
{
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("input.txt", "r", stdin);
#endif
    int t = read();
    while (t--)
    {
        int x = read();
        double s = x * x * (1 + pi / 2);
        printf("%.2f\n", s);
    }
    return 0;
}

D. 扔硬幣

鏈接:https://ac.nowcoder.com/acm/contest/5758/D
來源:牛客網

題目描述

有n枚硬幣,每枚硬幣扔出來是正面和反面的概率各佔50%。小明同時扔下了n枚硬幣後,已知至少有m枚硬幣是反面。請問恰好有k枚硬幣是正面的概率是多少。

輸入描述:

輸入t,代表有t組數據。每組數據輸入一個數n,m,k,代表有n枚硬幣,拋出以後至少有m枚是反面的情況下,恰好有k個正面的概率。
(t<=1000,n<1e5,m<=1000,k<=n)

輸出描述:

對於結果是p/q,輸出分數取模1e9+7後的結果。

示例1

輸入

複製

1
10 3 5

輸出

複製

797520667

概率 逆元 

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

typedef long long ll;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;

template<typename T = int>
inline const T read()
{
    T x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

template<typename T>
inline void write(T x)
{
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

const int mod = 1e9 + 7;
const int maxn = 1e5 + 10;
ll fac[maxn];

void init()
{
    fac[0] = 1;
    for (int i = 1; i <= 1e5; i++)
        fac[i] = fac[i - 1] * i % mod;
}

ll qpow(ll x, ll k)
{
    ll res = 1;
    while (k)
    {
        if (k & 1) res = res * x % mod;
        x = x * x % mod; k >>= 1;
    }
    return res;
}

ll com(int n, int m)
{
    return fac[n] * qpow(fac[m], mod - 2) % mod * qpow(fac[n - m], mod - 2) % mod;
}

int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("input.txt", "r", stdin);
#endif
    int t = read();
    init();
    while (t--)
    {
        int n = read(), m = read(), k = read();
        if (n < m + k)
        {
            cout << 0 << endl;
            continue;
        }
        ll a = com(n, k), b = qpow(2, n);
        for (int i = 0; i < m; i++) b = (b - com(n, i) + mod) % mod;
        ll res = a * qpow(b, mod - 2) % mod;
        cout << res << endl;
    }
    return 0;
}

E. 賽馬

鏈接:https://ac.nowcoder.com/acm/contest/5758/E
來源:牛客網

題目描述

一天小明與他同學準備賽馬,他們每人有n匹馬,每匹馬有一個固定的戰力值,戰力值高的馬會戰勝戰力值低的馬並贏得比賽。每匹馬只能出場比賽一次。小明偷看到了他對手每匹馬的出場順序,小明在更改自己馬出場順序後最多能贏多少場比賽。

輸入描述:

輸入t,代表有t組數據。每組數據輸入正整數n,每人的馬匹數量。下一行輸入n個值a[i],代表小明每匹馬的戰力值。接下來一行輸入n個值b[i],代表對手按順序出場的每匹馬的戰力值。(t<=10, n<1000,1<=i<=n,a[i]<1e6,b[i]<1e6)

輸出描述:

小明在更改馬匹出場順序後,最多能贏的場數。

示例1

輸入

複製

1
3
5 8 8
4 7 10

輸出

複製

2

二分查找 multiset 的妙用 

#include <bits/stdc++.h>
using namespace std;
 
typedef long long ll;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
multiset<int> s;
 
template<typename T = int>
inline const T read()
{
    T x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}
 
template<typename T>
inline void write(T x)
{
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}
 
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("input.txt", "r", stdin);
#endif
    int t = read();
    while (t--)
    {
        int n = read(), cnt = 0;
        s.clear();
        for (int i = 0; i < n; i++) s.insert(read());
        for (int i = 0; i < n; i++)
        {
            int v = read();
            auto it = s.upper_bound(v);
            if (*it > v)
            {
                s.erase(it);
                cnt++;
            }
        }
        cout << cnt << endl;
    }
    return 0;
}

F. 三角形

鏈接:https://ac.nowcoder.com/acm/contest/5758/F
來源:牛客網

題目描述

小明有一根長度爲a的木棒,現在小明想將木棒分爲多段(每段木棒長度必須爲整數),
使得分隔後的木棍中,取出的任意三段都不能構成三角形,小明想知道木棒最多被分成幾段?

輸入描述:

輸入數據的第一行是t,表示數據的組數, 接下來每組數據輸入一個a
(t<=1000, 1 <= a < 2^64 - 1)

輸出描述:

對於每組輸入樣例,打印木棒最多被分爲多少段

示例1

輸入

複製

2
1
3

輸出

複製

1
2

斐波那契數列任意兩項和唯一 

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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;

template<typename T = ull>
inline const T read()
{
    T x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

template<typename T>
inline void write(T x)
{
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("input.txt", "r", stdin);
#endif
    ll t = read();
    while (t--)
    {
        ull a = read(), now = 1, rec = 1, last = 0;
        int cnt = 0;
        while (a >= now)
        {
            a -= now;
            rec = now;
            now += last;
            last = rec;
            cnt++;
        }
        cout << cnt << endl;
    }
    return 0;
}

H. 直線

鏈接:https://ac.nowcoder.com/acm/contest/5758/H
來源:牛客網

題目描述

平面上存在n條直線。請問n條直線在平面上最多存在多少交點。

輸入描述:

輸入數據的第一行是t,表示數據的組數(t  < 100), 接下來每組數據輸入一個n(1<=n <= 1e15)

輸出描述:

對於每組輸入樣例,打印n條直線最多有多少個交點

示例1

輸入

複製

2
1
2

輸出

複製

0
1

防溢出 

#include <bits/stdc++.h>
using namespace std;
 
typedef long long ll;
typedef __int128 lll;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
 
template<typename T = lll>
inline const T read()
{
    T x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}
 
template<typename T>
inline void write(T x)
{
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}
 
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("input.txt", "r", stdin);
#endif
    int t = read();
    while (t--)
    {
        lll n = read();
        write(ans = n * (n - 1) / 2);
        putchar(10);
    }
    return 0;
}

J. 最大值

鏈接:https://ac.nowcoder.com/acm/contest/5758/J
來源:牛客網

題目描述

有一個字符串s,對於字符串中一個非前綴子串恰好爲字符串的前綴我們稱之爲ac串。
請問給出一個字符串他的ac串最大長度爲多少

輸入描述:

輸入數據第一行是t,表示數據的組數,接下來每組數據輸入一個字符串s
(t<=10,s<=1e5)

輸出描述:

輸出最大長度

示例1

輸入

複製

2
aaaaa
abacc

輸出

複製

4
1

說明

aaaab的ac串是aaa(2:4)
acac的ac串是ac(3:4)

KMP 算法 next 數列的性質 

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

typedef long long ll;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
int nxt[maxn];
char s[maxn];

template<typename T = int>
inline const T read()
{
    T x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

template<typename T>
inline void write(T x)
{
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

void getNext(size_t len)
{
    memset(nxt, 0, sizeof(nxt));
    for (int i = 2, j = 0; i <= len; i++)
    {
        while (j && s[i] != s[j + 1]) j = nxt[j];
        if (s[i] == s[j + 1]) j++;
        nxt[i] = j;
    }
}

int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("input.txt", "r", stdin);
#endif
    int t = read();
    while (t--)
    {
        scanf("%s", s + 1);
        size_t len = strlen(s + 1);
        getNext(len);
        int res = 0;
        for (int i = 1; i <= len; i++)
            res = max(res, nxt[i]);
        cout << res << endl;
    }
    return 0;
}

 

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