Educational Codeforces Round 97 (Rated for Div. 2)

A. Marketing Scheme
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You got a job as a marketer in a pet shop, and your current task is to boost sales of cat food. One of the strategies is to sell cans of food in packs with discounts.

Suppose you decided to sell packs with a cans in a pack with a discount and some customer wants to buy x cans of cat food. Then he follows a greedy strategy:

he buys ⌊xa⌋ packs with a discount;
then he wants to buy the remaining (xmoda) cans one by one.
⌊xa⌋ is x divided by a rounded down, xmoda is the remainer of x divided by a.

But customers are greedy in general, so if the customer wants to buy (xmoda) cans one by one and it happens that (xmoda)≥a2 he decides to buy the whole pack of a cans (instead of buying (xmoda) cans). It makes you, as a marketer, happy since the customer bought more than he wanted initially.

You know that each of the customers that come to your shop can buy any number of cans from l to r inclusive. Can you choose such size of pack a that each customer buys more cans than they wanted initially?

Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases.

The first and only line of each test case contains two integers l and r (1≤l≤r≤109) — the range of the number of cans customers can buy.

Output
For each test case, print YES if you can choose such size of pack a that each customer buys more cans than they wanted initially. Otherwise, print NO.

You can print each character in any case.

Example
inputCopy
3
3 4
1 2
120 150
outputCopy
YES
NO
YES

求一个数a 让[L,R]区间所有数x都满足 x % a >= a/2
首先检查左边界可以判断出,这个数最大不能超过2*L(这个数本身就不符合),所有对R做个判断就可以了
代码如下:

#include <bits/stdc++.h>

using namespace  std;

int main(void){
    int T;
    cin >> T;
    while(T--){
        int l,r;
        cin >> l >> r;
        if(r < 2*l){
            cout << "YES" << endl;
        }else{
            cout << "NO" << endl;
        }
    }
    return 0;
}

B. Reverse Binary Strings
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a string s of even length n. String s is binary, in other words, consists only of 0’s and 1’s.

String s has exactly n2 zeroes and n2 ones (n is even).

In one operation you can reverse any substring of s. A substring of a string is a contiguous subsequence of that string.

What is the minimum number of operations you need to make string s alternating? A string is alternating if si≠si+1 for all i. There are two types of alternating strings in general: 01010101… or 10101010…

Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases.

The first line of each test case contains a single integer n (2≤n≤105; n is even) — the length of string s.

The second line of each test case contains a binary string s of length n (si∈ {0, 1}). String s has exactly n2 zeroes and n2 ones.

It’s guaranteed that the total sum of n over test cases doesn’t exceed 105.

Output
For each test case, print the minimum number of operations to make s alternating.

Example
inputCopy
3
2
10
4
0110
8
11101000
outputCopy
0
1
2
Note
In the first test case, string 10 is already alternating.

In the second test case, we can, for example, reverse the last two elements of s and get: 0110 → 0101.

In the third test case, we can, for example, make the following two operations:

从左往右各贪心一次,左右两边选个最小的

代码如下:

#include <bits/stdc++.h>
 
using namespace  std;
typedef long long ll;
 
int solve(string str){
    int Count1 = 0;
    bool isok = true;
    for(int i = 0;i < str.size();i+=1){
        int val = str[i]-'0';
        if(val != (i%2)){
            isok = false;
        }else{
            if(!isok){
                Count1 += 1;
                isok = true;
            }
        }
    }
    if(!isok){
        Count1 += 1;
    }
    int Count2 = 0;
    isok = true;
    for(int i = 0;i < str.size();i+=1){
        int val = str[i]-'0';
        if(val == (i%2)){
            isok = false;
        }else{
            if(!isok){
                Count2 += 1;
                isok = true;
            }
        }
    }
    if(!isok){
        Count2 += 1;
    }
   // cout << Count1 << " " << Count2 << endl;
    return min(Count1,Count2);
}
int main(void){
    int T;
    cin >> T;
    while(T--){
        int N;
        cin >> N;
        string str;
        cin >> str;
        cout << solve(str) << endl;
    }
 
}

C. Chef Monocarp
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Chef Monocarp has just put n dishes into an oven. He knows that the i-th dish has its optimal cooking time equal to ti minutes.

At any positive integer minute T Monocarp can put no more than one dish out of the oven. If the i-th dish is put out at some minute T, then its unpleasant value is |T−ti| — the absolute difference between T and ti. Once the dish is out of the oven, it can’t go back in.

Monocarp should put all the dishes out of the oven. What is the minimum total unpleasant value Monocarp can obtain?

Input
The first line contains a single integer q (1≤q≤200) — the number of testcases.

Then q testcases follow.

The first line of the testcase contains a single integer n (1≤n≤200) — the number of dishes in the oven.

The second line of the testcase contains n integers t1,t2,…,tn (1≤ti≤n) — the optimal cooking time for each dish.

The sum of n over all q testcases doesn’t exceed 200.

Output
Print a single integer for each testcase — the minimum total unpleasant value Monocarp can obtain when he puts out all the dishes out of the oven. Remember that Monocarp can only put the dishes out at positive integer minutes and no more than one dish at any minute.

Example
inputCopy
6
6
4 2 4 4 5 2
7
7 7 7 7 7 7 7
1
1
5
5 1 2 4 3
4
1 4 4 4
21
21 8 1 4 1 5 21 1 8 21 11 21 11 3 12 8 19 15 9 11 13
outputCopy
4
12
0
0
2
21

比赛灵机一动,费用流搞过了,建图如下:
在这里插入图片描述

#include <bits/stdc++.h>
 
using namespace  std;
const int MAX_V = 610;
const int INF = 0x3f3f3f3f;
typedef long long ll;
typedef pair<int,int> P;
class Edge{
public:
    int to,cap,cost,rev;
    Edge(){}
    Edge(int _to,int _cap,int _cost,int _rev):to(_to),cap(_cap),cost(_cost),rev(_rev){}
};
int V;
vector<Edge> G[MAX_V];
int dist[MAX_V];
int prevv[MAX_V],preve[MAX_V];
void add_Edge(int from,int to,int cap,int cost){
    G[from].push_back(Edge(to,cap,cost,(int)G[to].size()));
    G[to].push_back(Edge(from,0,-cost,(int)G[from].size()-1));
}
void spfa(int s){
    fill(dist,dist+1+V,INF);
    dist[s] = 0;
    queue<int> que;
    que.push(s);
    while(!que.empty()){
        int v = que.front();que.pop();
        for(int i=0;i<G[v].size();++i){
            Edge &e = G[v][i];
            if(e.cap > 0 && dist[e.to] > dist[v] + e.cost){
                dist[e.to] = dist[v] + e.cost;
                prevv[e.to] = v;
                preve[e.to] = i;
                que.push(e.to);
            }
        }
    }
}
int min_cost_flow(int s,int t,int f){
    int res = 0;
    while(f > 0){
        spfa(s);
        if(dist[t] == INF)  return -1;
        int d = f;
        for(int v = t;v != s;v = prevv[v])
            d = min(d,G[prevv[v]][preve[v]].cap);
        f -= d;
        res += d*dist[t];
        for(int v = t;v != s;v = prevv[v]){
            Edge &e = G[prevv[v]][preve[v]];
            e.cap -= d;
            G[v][e.rev].cap += d;
        }
    }
    return res;
}
void clear(){
    for(int i=0;i < MAX_V;i += 1){
        G[i].clear();
    }
    memset(dist,0,sizeof(dist));
    memset(preve,0,sizeof(preve));
    memset(preve,0,sizeof(preve));
}
int main(void){
    int T,N;
    cin >> T;
    vector<int> vec,nums;
    while(T--){
        vec.clear();
        nums.clear();
        clear();
        cin >> N;
        int value;
        for(int i = 1;i <= N;i += 1){
            cin >>  value;
            vec.push_back(value);
            nums.push_back(i);
            nums.push_back(i+N);
        }
        V = 3*N+2;
        int s = 0,t = V-1;
 
        for(int i=0;i<vec.size();i+=1){
            add_Edge(s,i+1,1,0);
        }
        for(int i=0;i<vec.size();i+=1){
            for(int j=0;j<nums.size();j+=1){
                add_Edge(i+1,N+j+1,1,abs(vec[i]-nums[j]));
            }
        }
        for(int j=0;j<nums.size();j+=1){
            add_Edge(N+j+1,t,1,0);
        }

        cout << min_cost_flow(s,t,N) << endl;
 
 
    }
 
    return 0;
}

D. Minimal Height Tree
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Monocarp had a tree which consisted of n vertices and was rooted at vertex 1. He decided to study BFS (Breadth-first search), so he ran BFS on his tree, starting from the root. BFS can be described by the following pseudocode:

a = [] # the order in which vertices were processed
q = Queue()
q.put(1) # place the root at the end of the queue
while not q.empty():
k = q.pop() # retrieve the first vertex from the queue
a.append(k) # append k to the end of the sequence in which vertices were visited
for y in g[k]: # g[k] is the list of all children of vertex k, sorted in ascending order
q.put(y)
Monocarp was fascinated by BFS so much that, in the end, he lost his tree. Fortunately, he still has a sequence of vertices, in which order vertices were visited by the BFS algorithm (the array a from the pseudocode). Monocarp knows that each vertex was visited exactly once (since they were put and taken from the queue exactly once). Also, he knows that all children of each vertex were viewed in ascending order.

Monocarp knows that there are many trees (in the general case) with the same visiting order a, so he doesn’t hope to restore his tree. Monocarp is okay with any tree that has minimum height.

The height of a tree is the maximum depth of the tree’s vertices, and the depth of a vertex is the number of edges in the path from the root to it. For example, the depth of vertex 1 is 0, since it’s the root, and the depth of all root’s children are 1.

Help Monocarp to find any tree with given visiting order a and minimum height.

Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases.

The first line of each test case contains a single integer n (2≤n≤2⋅105) — the number of vertices in the tree.

The second line of each test case contains n integers a1,a2,…,an (1≤ai≤n; ai≠aj; a1=1) — the order in which the vertices were visited by the BFS algorithm.

It’s guaranteed that the total sum of n over test cases doesn’t exceed 2⋅105.

Output
For each test case print the minimum possible height of a tree with the given visiting order a.

比赛时没注意到每层都是ascending的。注意用后一个于当前做比较,代码如下:

#include <bits/stdc++.h>
 
using namespace std;
const int MAX = 2e5+10;
int a[MAX],N;
 
int solve(){
    int countLast = 1,countNow = 0,high = 0;
    bool newPointTag = true;
    queue<int> que;
    que.push(0);
    for(int i = 1;i < N;i += 1){
        int h = que.front();que.pop();
        que.push(h+1);
        while(i+1 < N && a[i+1] >= a[i]){
            que.push(h+1);
            i += 1;
        }
    }
    return que.back();
}
int main(void){
    int T;
    cin >> T;
    while(T--){
        cin >> N;
        for(int i = 0;i < N;i += 1){
            cin >> a[i];
        }
        cout << solve() << endl;
    }
    return 0;
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页