暑假训练三阶段day2

Jessica’s Reading Problem

Jessica's a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent little time on it. If she wants to pass it, she has to master all ideas included in a very thick text book. The author of that text book, like other authors, is extremely fussy about the ideas, thus some ideas are covered more than once. Jessica think if she managed to read each idea at least once, she can pass the exam. She decides to read only one contiguous part of the book which contains all ideas covered by the entire book. And of course, the sub-book should be as thin as possible.

A very hard-working boy had manually indexed for her each page of Jessica's text-book with what idea each page is about and thus made a big progress for his courtship. Here you come in to save your skin: given the index, help Jessica decide which contiguous part she should read. For convenience, each idea has been coded with an ID, which is a non-negative integer.

Input

The first line of input is an integer P (1 ≤ P ≤ 1000000), which is the number of pages of Jessica's text-book. The second line contains P non-negative integers describing what idea each page is about. The first integer is what the first page is about, the second integer is what the second page is about, and so on. You may assume all integers that appear can fit well in the signed 32-bit integer type.

Output

Output one line: the number of pages of the shortest contiguous part of the book which contains all ideals covered in the book.

Sample Input

5
1 8 8 8 1

Sample Output

2

题意:一本书有P页,每一页都一个知识点,求去最少的连续页数覆盖所有的知识点。

题解:尺取法去覆盖区间

#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<cstdio>
using namespace std;
const int N = 100010;

int a[N], n, cnt, ans = 0x3f3f3f3f;
map<int, int> vis;
set<int> s;

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


int main(void) {
    n = read();
    for (int i = 1; i <= n; i++) {
        a[i] = read();
        s.insert(a[i]);
    }
    int l = 1, r = 1;
    while (r <= n) {
        if (!vis[a[r]]) {
            cnt++;
        }
        vis[a[r]]++;
        r++;
        while (cnt == s.size()) {
            vis[a[l]]--;
            if (!vis[a[l]]) cnt--;
            l++;
            ans = min(ans, r - l + 1);
        }
    }
    cout << ans << endl;
}

Bound Found

Signals of most probably extra-terrestrial origin have been received and digitalized by The Aeronautic and Space Administration (that must be going through a defiant phase: "But I want to use feet, not meters!"). Each signal seems to come in two parts: a sequence of n integer values and a non-negative integer t. We'll not go into details, but researchers found out that a signal encodes two integer values. These can be found as the lower and upper bound of a subrange of the sequence whose absolute value of its sum is closest to t.

You are given the sequence of n integers and the non-negative target t. You are to find a non-empty range of the sequence (i.e. a continuous subsequence) and output its lower index l and its upper index u. The absolute value of the sum of the values of the sequence from the l-th to the u-th element (inclusive) must be at least as close to t as the absolute value of the sum of any other non-empty range. 

Input
The input file contains several test cases. Each test case starts with two numbers n and k. Input is terminated by n=k=0. Otherwise, 1<=n<=100000 and there follow n integers with absolute values <=10000 which constitute the sequence. Then follow k queries for this sequence. Each query is a target t with 0<=t<=1000000000.
Output
For each query output 3 numbers on a line: some closest absolute sum and the lower and upper indices of some range where this absolute sum is achieved. Possible indices start with 1 and go up to n.
Sample Input

5 1
-10 -5 0 5 10
3
10 2
-9 8 -7 6 -5 4 -3 2 -1 0
5 11
15 2
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
15 100
0 0

Sample Output

5 4 4
5 2 8
9 1 1
15 1 15
15 1 15

题意:给出 n 个数字以及 k 个 s 值,求区间总和的绝对值中最接近 s 的一个区间,要求输出总和的绝对值与左、右端点

题解:尺取法

#include <algorithm>
#include<iostream>
#include <climits>

using namespace std;
const int maxn = 1e5 + 100;

int t, n, m;
pair<int, int> p[maxn];

int main(void) {
    while (cin >> n >> m && n + m) {
        p[0] = make_pair(0, 0);
        for (int i = 1; i <= n; i++) {
            int tmp;
            cin >> tmp;
            p[i] = make_pair(p[i - 1].first + tmp, i);
        }
        sort(p, p + n + 1);
        while (m--) {
            cin >> t;
            int l, r, sum = INT_MAX, ansl, ansr, ans = INT_MAX;
            l = 0;
            r = 1;
            while (r <= n) {
                int temp = p[r].first - p[l].first;
                if (abs(temp - t) < ans) {
                    ans = abs(temp - t);
                    sum = temp;
                    ansl = min(p[l].second, p[r].second);
                    ansr = max(p[l].second, p[r].second);
                }
                if (temp < t) r++;
                else l++;
                if (l == r)
                    r++;
            }
            cout << sum << " " << ansl+1 << " " << ansr << endl;
        }
    }
    return 0;
}

Subsequence

A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, and a positive integer S (S < 100 000 000) are given. Write a program to find the minimal length of the subsequence of consecutive elements of the sequence, the sum of which is greater than or equal to S.

Input
The first line is the number of test cases. For each test case the program has to read the numbers N and S, separated by an interval, from the first line. The numbers of the sequence are given in the second line of the test case, separated by intervals. The input will finish with the end of file.
Output
For each the case the program has to print the result on separate line of the output file.if no answer, print 0.
Sample Input

2
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5

Sample Output

2
3

题意:当a1, a2 , a3 满足和>=S,得到一个区间长度3,那么去掉开头a1, 剩下 a2,a3,判断是否满足>=S,如果满足,那么区间长度更新,如果不满足,那么尾部向后拓展,判断a2,a3,a4是否满足条件。重复这样的操作。

#include<iostream>
#include<algorithm>

using namespace std;
const int N = 100010;
int num[N];

int main(void) {

    int n, s;
    int t;
    cin >> t;
    for (int i = 0; i < t; i++) {
        cin >> n >> s;
        for (int j = 0; j < n; j++) {
            cin >> num[j];
        }
        int sum = 0, minn = 1e9 + 10, l, k = 0;
        for (int j = 0; j < n; j++) {
            sum += num[j];
            if (sum >= s) {
                l = j - k + 1;
                minn = min(minn, l);
                sum -= num[k];
                sum -= num[j];
                k++, j--;
            }
        }
        if (minn == 1e9 + 10)
            cout << 0 << endl;
        else
            cout << minn << endl;
    }
    return 0;
}

Tallest Cow

FJ's N (1 ≤ N ≤ 10,000) cows conveniently indexed 1..N are standing in a line. Each cow has a positive integer height (which is a bit of secret). You are told only the height H (1 ≤ H ≤ 1,000,000) of the tallest cow along with the index I of that cow.

FJ has made a list of R (0 ≤ R ≤ 10,000) lines of the form "cow 17 sees cow 34". This means that cow 34 is at least as tall as cow 17, and that every cow between 17 and 34 has a height that is strictly smaller than that of cow 17.

For each cow from 1..N, determine its maximum possible height, such that all of the information given is still correct. It is guaranteed that it is possible to satisfy all the constraints.

Input
Line 1: Four space-separated integers: N, I, H and R
Lines 2…R+1: Two distinct space-separated integers A and B (1 ≤ A, B ≤ N), indicating that cow A can see cow B.
Output
Lines 1…N: Line i contains the maximum possible height of cow i.
Sample Input

9 3 5 5
1 3
5 3
4 3
3 7
9 8

Sample Output

5
4
5
3
4
4
5
5
5

题意:现在有 N 头奶牛,已知第 I 头牛是所有牛中最高的牛,身高为 H ;我们还知道 R 种关系,每一种关系包含的 a , b 表示第 a 头牛可以看见第 b 头牛(即第 b 头牛的身高不低于第 a 头牛的身高,并且它们中间的牛的身高都不高于 a 的身高),求每头牛的最高可能身高。

题解:差分来确定身高差

#include <map>
#include <iostream>
#include <algorithm>

using namespace std;
map<pair<int, int>, bool> v;
int s[10000010];

int main(void) {
    int t, n, p, h;
    cin >> n >> p >> h >> t;
    while (t--) {
        int a, b;
        cin >> a >> b;
        if (a > b) swap(a, b);
        if (v[make_pair(a, b)]) continue;
        s[a + 1]--;
        s[b]++;
        v[make_pair(a, b)] = true;
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        ans += s[i];
        cout << h + ans << endl;
    }
    return 0;
}

Straight Master

A straight is a poker hand containing five cards of sequential rank, not necessarily to be the same suit. For example, a hand containing 7 club, 6 spade, 5 spade, 4 heart and 3 diamond forms a straight. In this problem, we extend the definition of a straight to allow 3 to 5 cards of sequential rank. Hence a hand containing K spade, Q club, and J heart is also a straight.

Mr. Panda is playing a poker game called Straight Master. The game uses a large deck of card that has N ranks from 1 to N. The rule of the game is simple: split the cards in Mr. Panda's hand into several straights of length from 3 to 5.

Now given a hand of cards, can you help Mr. Panda to determine if it is possible to split the cards into straights?

Input

The first line of the input gives the number of test cases, T. T test cases follow.

Each test case contains two lines. The first line contains an integer N, indicating the number of ranks in the deck. The next line contains N integers a1, a2, ..., aN indicating the number of cards for each rank in Mr. Panda's hand.

    1 ≤ T ≤ 100.
    1 ≤ N ≤ 2 × 105.
    0 ≤ ai ≤ 109.
    .

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 if Mr. Panda can split all his cards into straights of length from 3 to 5, or No otherwise.

Example
Input

2
13
1 2 2 1 0 0 0 0 0 0 0 0 0
13
1 1 1 1 0 1 1 0 0 0 0 0 0

Output

Case #1: Yes
Case #2: No

Note

In the first test case, Mr. Panda can split his cards into two straights: [1, 2, 3] and [2, 3, 4]. In the second test case, there is no way to form a straight for card 6 and 7.

题意和题解

非常男女

近来,蒜头君致力于研究班上同学的配对问题(别想太多,仅是舞伴),通过各种推理和实验,他掌握了大量的实战经验。例如,据他观察,身高相近的人似乎比较合得来。

万圣节来临之际,蒜头君准备在学校策划一次大型的“非常男女”配对活动。对于这次活动的参与者,蒜头君有自己独特的选择方式。他希望能选择男女人数相等且身高都很接近的一些人。这种选择方式实现起来很简单。他让学校的所有人按照身高排成一排,然后从中选出连续的若干个人,使得这些人中男女人数相等。为了使活动更热闹,蒜头君当然希望他能选出的人越多越好。请编写程序告诉他,他最多可以选出多少人来。
输入格式

第一行有一个正整数 $n\ (1\le n \le 10^5)$,代表学校的人数。

第二行有 $n$ 个用空格隔开的数,这些数只能是 $0$ 或 $1$,其中,$0$ 代表一个女生,$1$代表一个男生。
输出格式

输出一个非负整数,这个数表示在输入数据中最长的一段男女人数相等的连续子序列长度。

Sample Input

9
0 1 0 0 0 1 1 0 0

Sample Output

6

题解:0转成-1前缀和找前后最长两个相等的区间

#include<iostream>

using namespace std;

const int N = 1e6 + 10;
int a[N];

int main(void) {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        if (x == 0)
            x = -1;
        a[i] = x + a[i - 1];
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < i; j++) {
            if (a[i] == a[j]) {
                ans = max(ans, i - j);
                break;
            }
        }
    }
    cout << ans << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值