ICPC North Central NA Contest 2018

B. Maximum Subarrays

You may have heard of the "maximum subarray problem'' from your university's undergraduate algorithms course. The problem goes like this: You are given an array AA of nn integers, and the task is to find a contiguous subarray of AA whose sum is maximum. For example, in the array below:

A := [-2, 3, 5, -7, 8, 13, -20, 14, 1]A:=[−2,3,5,−7,8,13,−20,14,1]

the solution is the subarray from the second index (the number 33) to the sixth index (the number 1313), with total sum 2222. The problem can be solved via divide and conquer, in O(n \log n)O(nlogn) time, or dynamic programming, in O(n)O(n) time.

 

Being a strong student in algorithms yourself, you are of course familiar with both approaches, so we won't bother explaining them here. However, your classmate Steve, a not-so-strong student in algorithms, has been bragging to you about the maximum subarray problem. He claims that not only can he solve the maximum subarray problem in linear time, he can even solve what he calls the "kk-maximum subarray problem,'' ALSO in linear time! What is the "kk-Maximum subarray problem,'' you ask? In a condescending tone, Steve explains: It is the natural generalization of the maximum subarray problem. Given an array AA of nn integers, you must find kkdisjoint, contiguous subarrays of AA so that their total sum is maximum.

You're not at all confident that Steve knows how to solve the "kk-maximum subarray problem'' in linear time, let alone that there even exists a linear time solution. You have gone to every algorithms lecture, however, a near-infinite improvement on Steve's attendance, and so you believe if anyone is to be the authority on the problem, it probably should be you.

You decide to write a program to solve the "kk-maximum subarray problem.'' You can use this to verify Steve's likely-incorrect algorithm. To simplify things, you make the program just output the value of an optimal solution. You can modify it later if you want the solution itself. Furthermore, you decide your algorithm is sufficiently efficient as long as its running time is bounded by a small polynomial in nn and kk. You think coming up with an actually-correct linear time solution would probably take you awhile, and you've decided you only want to spend, say, a maximum of five hours on your code.

Input

The input will consist of two lines. On the first line are the integers nn and kk, (1 \leq k \leq n \leq 5\,0001≤k≤n≤5000). On the second line are nn integers, representing the array AA. The integers in array AA will be between -10^9−109 and 10^9109, inclusive.

Output

Output the maximum possible total sum of kk disjoint contiguous subarrays of array AA. Although the subarrays are required to be disjoint, a subarray may end at index ii and another subarray start at index i+1i+1. No subarray is allowed to be empty.

輸出時每行末尾的多餘空格,不影響答案正確性

樣例輸入1複製

9 1
-2 3 5 -7 8 13 -20 14 1

樣例輸出1複製

22

樣例輸入2複製

11 3
23 -10 12 -2 -33 13 -5 55 23 -8 13

樣例輸出2複製

126

最大M字段和裸題

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 +7;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const int N = 5e3 + 10;

ll dp[N];
ll pre[N];
ll a[N];

int main()
{
    int n, m;
    while(~scanf("%d%d", &n, &m))
    {
        for(int i = 1; i <= n; ++i)
        {
            scanf("%lld", &a[i]);
        }
        memset(dp, 0, sizeof(dp));
        memset(pre, 0, sizeof(pre));
        ll maxx = -inf;

//        dp[i][j] = max(dp[i][j], dp[i - 1][k] + a[j], dp[i][j - 1] + a[j]);
        for(int i = 1; i <= m; ++i)         ///m段
        {
            maxx = -inf;
            for(int j = i; j <= n; ++j)     ///在[0, j]內截了i段
            {
                dp[j] = max(pre[j - 1], dp[j - 1]) + a[j];
                pre[j - 1] = maxx;
                maxx = max(maxx, dp[j]);
            }
        }
        cout<<maxx<<'\n';
    }
    return 0;
}

 C. Rational Ratio

Every (positive) rational number can be expressed as a ratio of two (positive) integers.However, in decimal form, rational numbers often have an infinitely repeating pattern, e.g., 1/7 = 0.1428571428571428571/7=0.142857142857142857... A convenient way of writing this repeating pattern is to put a bar over the first occurrence of the repeating part, so 1/71/7 would be written:

 

0.\overline{142857}.0.142857.

 

Given a rational number consisting of a series of digits, followed by a decimal point, followed by more digits, and then a number indicating how many of the rightmost digits repeat (i.e., the number of digits under the bar), your task is to find the ratio of two integers, in the most reduced form, that represent the same rational number. For example, for the input 0.1428570.142857 66 you should find 1/71/7.

Input

The input will be a single line with two numbers separated by one space. The first number will consist of 11 to 33digits (00--99), followed by a decimal point, followed by 11 to 1111 digits (00--99), representing the decimal form of the number, possibly with leading zeros. The second number will be a positive integer indicating how many of the rightmost digits of the preceding number repeat. The first number will always be greater than 00. The second number will never be less than 11 nor larger than the number of digits to the right of the decimal point.

Output

Print the corresponding fraction in its most reduced form, that is, the fraction with the smallest possible integer values in the numerator and denominator.

輸出時每行末尾的多餘空格,不影響答案正確性

樣例輸入1複製

0.142857 6

樣例輸出1複製

1/7

樣例輸入2複製

1.6 1

樣例輸出2複製

5/3

樣例輸入3複製

123.456 2

樣例輸出3複製

61111/495

題意:

將無線循環小數轉化爲分數

將原數擴大,減去小數部分

如 x = 12.25343434......

10000x - 100x = 122534.343434...... - 1225.343434..... = 121309

x = 121309 / 9900

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
const double PI = acos(-1.0);
const int N = 2e3 + 10;

ll gcd(ll a, ll b)
{
    return b ? gcd(b, a % b) : a;
}

int main()
{
    string s;
    ll a, b, c;
    while(cin >> s >> c)
    {
        int len = s.size();
        ll big = 0;
        ll lit = 0;
        int id;
        for(int i = 0; i < len; ++i)
        {
            if(s[i] == '.')
            {
                id = i;
            }
            else
            {
                big *= 10;
                big += s[i] - '0';
            }
        }
        for(int i = 0; i < len - c; ++i)
        {
            if(s[i] != '.')
            {
                lit *= 10;
                lit += s[i] - '0';
            }
        }
//        cout<<lit<<' '<<big<<'\n';
        int tmp = len - c - 1 - id;
        ll bi = 1;
        ll li = 1;
        for(int i = 1; i <= tmp + c; ++i)
        {
            if(i <= tmp)
            {
                li *= 10;
            }
            bi *= 10;
        }
        ll up = big - lit;
        ll down = bi - li;
        ll gcdd = gcd(up, down);
        up /= gcdd;
        down /= gcdd;
        cout<<up<<'/'<<down<<'\n';
    }
    return 0;
}

 E. Euler's Number

Euler's number (you may know it better as just ee) has a special place in mathematics. You may have encountered ee in calculus or economics (for computing compound interest), or perhaps as the base of the natural logarithm, \ln{x}lnx, on your calculator.

While ee can be calculated as a limit, there is a good approximation that can be made using discrete mathematics. The formula for ee is:

 

e=\sum_{i=0}^{n}\frac{1}{i!}=\frac{1}{0!}+\frac{1}{1!}+\frac{1}{2!}+\frac{1}{3!}+\frac{1}{4!}+\cdotse=∑i=0n​i!1​=0!1​+1!1​+2!1​+3!1​+4!1​+⋯

 

Note that 0! = 10!=1. Now as nn approaches \infty∞, the series converges to ee. When nn is any positive constant, the formula serves as an approximation of the actual value of ee. (For example, at n=10n=10 the approximation is already accurate to 77 decimals.)

You will be given a single input, a value of nn, and your job is to compute the approximation of ee for that value of nn.

Input

A single integer nn, ranging from 00 to 10\,00010000.

Output

A single real number -- the approximation of ee computed by the formula with the given nn. All output must be accurate to an absolute or relative error of at most 10^{-12}10−12.

本題答案不唯一,符合要求的答案均正確

樣例輸入1複製

3

樣例輸出1複製

2.6666666666666665

樣例輸入2複製

15

樣例輸出2複製

2.718281828458995

暴力,精確到小數點後12位,數很小的時候break

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
const double PI = acos(-1.0);
const int N = 2e3 + 10;

int main()
{
    int n;
    while(~scanf("%d", &n))
    {
        double ans = 1;
        ll tmp = 1;
        for(int i = 1; i <= min(18, n); ++i)
        {
            tmp *= i;
            ans += 1.0 / tmp;
        }
        printf("%.15f\n", ans);
    }
    return 0;
}

 F. Lipschitz Constant

Today you are doing your calculus homework, and you are tasked with finding a Lipschitz constant for a function f(x)f(x), which is defined for NN integer numbers xx and produces real values.Formally, the Lipschitz constant for a function ff is the smallest real number LL such that for any xx and yy with f(x)f(x) and f(y)f(y) defined we have:

|f(x) - f(y)| \leq L \cdot |x - y|.∣f(x)−f(y)∣≤L⋅∣x−y∣.

 

Input

The first line contains NN -- the number of points for which ff is defined. The next NN lines each contain an integer xx and a real number zz, which mean that f(x) = zf(x)=z. Input satisfies the following constraints:

  • 2 \leq N \leq 200\,0002≤N≤200000.

  • All xx and zz are in the range -10^9 \leq x,z \leq 10^9−109≤x,z≤109.

  • All xx in the input are distinct.

Output

Print one number -- the Lipschitz constant. The result will be considered correct if it is within an absolute error of 10^{-4}10−4 from the jury's answer.

本題答案不唯一,符合要求的答案均正確

樣例輸入1複製

3
1 1
2 2
3 4

樣例輸出1複製

2

樣例輸入2複製

2
1 4
2 2

樣例輸出2複製

2

樣例輸入3複製

4
-10 6.342
-7 3
46 18.1
2 -34

樣例輸出3複製

4.111111111

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
const double PI = acos(-1.0);
const int N = 2e5 + 10;

struct node
{
    int x;
    double a;
}s[N];

bool cmp(node p, node q)
{
    if(p.x != q.x)
        return p.x < q.x;
    else
        return p.a > q.a;
}

int main()
{
    int n;
    while(~scanf("%d", &n))
    {
        for(int i = 1; i <= n; ++i)
        {
            scanf("%d%lf", &s[i].x, &s[i].a);
        }
        sort(s + 1, s + n + 1, cmp);
        double maxx = 0.0;
        for(int i = 2; i <= n; ++i)
        {
            maxx = max(maxx, 1.0 * fabs(s[i].a - s[i - 1].a) / abs(s[i].x - s[i - 1].x));
        }
        printf("%.5f\n", maxx);
    }
    return 0;
}

 G. Tima goes to Xentopia

The city of Xentopia has a well-connected railway network. The city has NN junctions numbered from 11 to NN.There are MM pairs of railway tracks that exist between the junctions. Trains can travel in both directions on each track.Each railway track is labelled either red, blue, or white in colour.

Tima, a tourist in the city, wants to travel from junction SS to junction TT in the minimum possible time.She has a map of the railway network that she can use to achieve this goal.

Tima, being rather eccentric, has an interesting constraint for her travel: She wants to travel via exactly k_1k1​ red tracks, exactly k_2k2​ blue tracks, and any number of white tracks, in any order. She is fine with using a railway track more than once.

Can you tell the minimum time Tima will take to go from SS to TT, ensuring that her constraint is not violated?

Input

The first line contains four space-separated integers: NN, (1 \leq N \leq 4501≤N≤450); MM, (1 \leq M \leq 1\,1001≤M≤1100); k_1k1​; and k_2k2​, (0 \leq k_1, k_2 \leq 8000≤k1​,k2​≤800, k_1 \cdot k_2 \leq 800k1​⋅k2​≤800). Following are MM lines. Each line contains four space-separated integers: U~V~X~CU V X C, denoting that a track exists between junction UU and junction VV, (1 \leq U, V \leq N1≤U,V≤N, U \neq VU​=V); the train covers this track in XX seconds, (0 \leq X \leq 10^90≤X≤109); and the track is labelled colour CC, (0 \leq C \leq 20≤C≤2). A white track is denoted by C=0C=0, a red track is denoted by C=1C=1, and a blue track is denoted by C=2C=2.

The last line contains two space-separated integers SS, (1 \leq S \leq N1≤S≤N), and TT, (1 \leq T \leq N1≤T≤N), the source and destination of Tima's journey, respectively.Note: SS may be equal to TT.

Output

Print a single integer denoting the total time Tima would take. If it is not possible for Tima to reach her destination using exactly k_1k1​ red tracks, k_2k2​ blue tracks, and any number of white tracks, output -1−1.

輸出時每行末尾的多餘空格,不影響答案正確性

樣例輸入1複製

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

樣例輸出1複製

2

樣例輸入2複製

4 3 200 1
1 2 1 1
2 3 1 0
2 4 1 2
1 3

樣例輸出2複製

-1

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-12;
const double PI = acos(-1.0);
const int N = 455;
const int M = 2205;

int head[N];
ll dis[N][M];
int id[805][805];
int n, m, tot, k1, k2, s, t;

struct Node
{
    int u, v, c, next;
    ll l;
}edge[M];

struct A
{
    int pos, red, blue;
    ll cost;
    A(){}
    A(int a, int b, int c, ll d):pos(a), red(b), blue(c), cost(d){}
    bool operator < (const A &a)const
    {
        return cost > a.cost;
    }
};

void init()
{
    memset(head, -1, sizeof(head));
    tot = 0;
    int num = 0;
    for(int i = 0; i <= k1; ++i)
    {
        for(int j = 0; j <= k2; ++j)
        {
            id[i][j] = ++num;
        }
    }
    for(int i = 0; i < N; ++i)
        for(int j = 0; j < M; ++j)
            dis[i][j] = inf;
}

void addedge(int x, int y, ll z, int c)
{
    edge[tot].u = x;
    edge[tot].v = y;
    edge[tot].l = z;
    edge[tot].c = c;
    edge[tot].next = head[x];
    head[x] = tot++;
}

ll dijk(int src, int des)
{
    priority_queue<A>q;
    dis[src][id[0][0]] = 0;
    q.push(A(src, 0, 0, 0));
    while(q.size())
    {
        A now = q.top();
        q.pop();
        int u = now.pos;
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].v;
            int c = edge[i].c;
            int fr = now.red;
            int fb = now.blue;
            if(c == 1)
                fr++;
            else if(c == 2)
                fb++;
            if(fr > k1 || fb > k2)
                continue;
            if(dis[v][id[fr][fb]] > dis[u][id[now.red][now.blue]] + edge[i].l)
            {
                dis[v][id[fr][fb]] = dis[u][id[now.red][now.blue]] + edge[i].l;
                q.push(A(v, fr, fb, dis[v][id[fr][fb]]));
            }
        }
    }
    return dis[des][id[k1][k2]];
}

int main()
{
    int u, v, c;
    ll w;
    while(~scanf("%d%d%d%d", &n, &m, &k1, &k2))
    {
        init();
        for(int i = 1; i <= m; ++i)
        {
            scanf("%d%d%lld%d", &u, &v, &w, &c);
            addedge(u, v, w, c);
            addedge(v, u, w, c);
        }
        scanf("%d%d", &s, &t);
        ll ans = dijk(s, t);
        if(ans == inf)
            ans = -1;
        cout<<ans<<'\n';
    }
    return 0;
}

 

 I. Other Side

John Doe wants to transport his possessions from one bank of Lake Michigan to the other. His possessions consist of WW wolves, SS sheep, and CC cabbages. The transportation will be carried out using a boat that can hold up to KK of these items at the same time. During each step, John can take some items from one bank and transfer them to the other bank. Unfortunately,when left unsupervised, wolves will eat sheep and sheep will eat cabbages (but wolves don't eat cabbages). John doesn't want to lose his possessions, so he has to devise a scheme such that this doesn't happen. With John present, any combination of items is allowed (both on the bank and in the boat). This is also true during the loading process. Since John isn't very good at solving problems like this, he asks you to help him.

Input

Input contains a single line with four integers: WW, SS, CC, KK. The input satisfies the following constraints:

0 \leq W, S, C, K \leq 10^6,0≤W,S,C,K≤106,

1 \leq max(W, S, C).1≤max(W,S,C).

 

Output

If it's possible to perform the transportation without the loss of items, print "YES", otherwise print "NO".

輸出時每行末尾的多餘空格,不影響答案正確性

樣例輸入1複製

1 1 1 1

樣例輸出1複製

YES

樣例輸入2複製

2 2 0 1

樣例輸出2複製

NO

題意:

農夫有W匹狼,S只羊,C顆菜,當農夫不在場的時候狼會吃羊,羊會吃菜,但狼不吃菜。船的最大容量是K,農夫要將貨物運到河對岸,問貨物是否收到損失

思路:

羊必須和狼和菜分開,將狼和菜看成一個整體,狼和菜一起運,或者是隻運羊。

(1)如果S < K || W + C < K,Yes

         船上可以裝下全部的羊,或者可以裝下全部的狼和菜,可以把少的一方一直放在船上,把多的一方分多趟運到對岸。

(2)如果S == K && W + C <= 2 * K

         船上放上全部的羊就滿了,先把 K 只羊運到對岸,再把 K 個狼和菜運到對岸,再將羊運回起點,將剩下的狼和菜全部運到           對岸,最後再運羊。可以發現,當W + C <= 2 * K時可以成功。

(3)如果 W + C == K && S <= 2 * K

         同(2)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
const double PI = acos(-1.0);
const int N = 2e3 + 10;

int main()
{
    int w, s, c, k;
    while(~scanf("%d%d%d%d", &w, &s, &c, &k))
    {
        bool flag = 0;
        if(s < k || w + c < k)
            flag = 1;
        if(s == k && w + c <= 2 * k)
            flag = 1;
        if(w + c == k && s <= 2 * k)
            flag = 1;
        if(flag)
            cout<<"YES"<<'\n';
        else
            cout<<"NO"<<'\n';
    }
    return 0;
}

 J. Kaleidoscopic Palindromes

Nicholas Neverson was a student at Northlings Neverland Academy. As with any daydreaming student, Nicholas was playing around with a Kaleidoscope one day instead of paying attention to the teacher. Since this was math class, his daydreams quickly turned to palindromic numbers. A palindromic number is any number which reads the same forwards and backwards.

He describes his vision to you at lunch: numbers which are palindromic in several bases at once. Nicholas wonders how many such numbers exist.You decide you can quickly code up a program that given a range and a number kk, outputs the number of numbers palindromic in all bases jj, 2 \leq j \leq k2≤j≤k, in that range.

Input

Input consists of three space-separated integers: aa, bb, and kk. The input satisfies the following constraints:

0 \leq a \leq b \leq 2\,000\,000,0≤a≤b≤2000000,

2 \leq k \leq 100\,000.2≤k≤100000.

 

Output

Output the quantity of numbers between aa and bb inclusive which are palindromes in every base jj, for 2 \leq j \leq k2≤j≤k.

輸出時每行末尾的多餘空格,不影響答案正確性

樣例輸入1複製

1 356 2

樣例輸出1複製

36

樣例輸入2複製

18 118 13

樣例輸出2複製

0

題意:

[a, b]內有多少用[1, k]內的任意進製表示都是迴文數的數

k越大時,數量越少

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const double eps = 1e-12;
const double PI = acos(-1.0);
const int N = 1e6 + 10;

int s[N];

bool check(int i, int j)
{
    int tot = 0;
    while(i)
    {
        s[++tot] = i % j;
        i /= j;
    }
    for(int k = 1; k <= tot / 2; ++k)
    {
        if(s[k] != s[tot - k + 1])
        {
            return 0;
        }
    }
    return 1;
}

int main()
{
    int a, b, k, ans = 0;
    cin >> a >> b >> k;
    for(int i = a; i <= b; ++i)
    {
        bool flag = 1;
        for(int j = 2; j <= k; ++j)
        {
            if(!check(i, j))
            {
                flag = 0;
                break;
            }
        }
        if(flag)
            ans++;
    }
    cout<<ans<<'\n';
    return 0;
}

 

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