“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛(同步赛)

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 
using namespace std;

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

template
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
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个半圆,求图形的面积

 

“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛(同步赛)_第1张图片

输入描述:

输入t,代表有t组数据。每组数据输入正整数x,代表正方形的边长。(t<100, x<1000)

输出描述:

输出图形面积,并保留2位小数,其中π取3.14。

示例1

输入

复制

1
1

输出

复制

2.57

注意用 3.14 代替 PI

#include 
using namespace std;

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

template
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
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 
using namespace std;

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

template
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
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 
using namespace std;
 
typedef long long ll;
typedef pair p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
multiset s;
 
template
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
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 
using namespace std;

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

template
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
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 
using namespace std;
 
typedef long long ll;
typedef __int128 lll;
typedef pair p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
 
template
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
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 
using namespace std;

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

template
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
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;
}

 

你可能感兴趣的:(XCPC)