Codeforces Round #375 (Div. 2)題解報告

此文章可以使用目錄功能喲↑(點擊上方[+])

終測C題被卡,居然是題目理解錯了,我這英語水平也是夠了...

鏈接→Codeforces Round #375 (Div. 2)

 Problem A-The New Year: Meeting Friends

Accept: 0    Submit: 0
Time Limit: 1 second    Memory Limit : 256 megabytes

 Problem Description

There are three friend living on the straight line Ox in Lineland. The first friend lives at the point x1, the second friend lives at the point x2, and the third friend lives at the point x3. They plan to celebrate the New Year together, so they need to meet at one point. What is the minimum total distance they have to travel in order to meet at some point and celebrate the New Year?

It's guaranteed that the optimal answer is always integer.

 Input

The first line of the input contains three distinct integers x1, x2 and x3 (1 ≤ x1, x2, x3 ≤ 100) — the coordinates of the houses of the first, the second and the third friends respectively.

 Output

Print one integer — the minimum total distance the friends need to travel in order to meet together.

 Sample Input

7 1 4
30 20 10

 Sample Output

6
20

 Hint

In the first sample, friends should meet at the point 4. Thus, the first friend has to travel the distance of 3 (from the point 7 to the point 4), the second friend also has to travel the distance of 3 (from the point 1 to the point 4), while the third friend should not go anywhere because he lives at the point 4.

 Problem Idea

解題思路:

【題意】

一維座標軸上有三個點x1,x2,x3

讓你確定一個點,使得三個點到該點的距離之和最小

輸出該最小距離之和

【類型】
簽到題,考查思維
【分析】

假設三個點x1,x2,x3到點x的距離之和爲d,那麼


要使得d儘可能小,我們不妨分情況討論一下,不過在分情況討論之前,爲了方便分析,我們先規定一下x3>x2>x1:




綜上所述,當且僅當x=x2時,即取中間點作爲目標點時,距離之和最小

【時間複雜度&&優化】
O(1)

題目鏈接→Codeforces Problem 723A The New Year: Meeting Friends

 Source Code

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define eps 1e-9
#define LL long long
#define PI acos(-1.0)
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 100005;
const int M = 100005;
const int inf = 1000000007;
const int mod = 101;
int s[3];
int main()
{
    int i;
    for(i=0;i<3;i++)
        scanf("%d",&s[i]);
    sort(s,s+3);
    printf("%d\n",s[2]-s[0]);
    return 0;
}

 Problem B-Text Document Analysis

Accept: 0    Submit: 0
Time Limit: 1 second    Memory Limit : 256 megabytes

 Problem Description

Modern text editors usually show some information regarding the document being edited. For example, the number of words, the number of pages, or the number of characters.

In this problem you should implement the similar functionality.

You are given a string which only consists of:

  • uppercase and lowercase English letters,
  • underscore symbols (they are used as separators),
  • parentheses (both opening and closing).

It is guaranteed that each opening parenthesis has a succeeding closing parenthesis. Similarly, each closing parentheses has a preceding opening parentheses matching it. For each pair of matching parentheses there are no other parenthesis between them. In other words, each parenthesis in the string belongs to a matching "opening-closing" pair, and such pairs can't be nested.

For example, the following string is valid: "_Hello_Vasya(and_Petya)__bye_(and_OK)".

Word is a maximal sequence of consecutive letters, i.e. such sequence that the first character to the left and the first character to the right of it is an underscore, a parenthesis, or it just does not exist. For example, the string above consists of seven words: "Hello", "Vasya", "and", "Petya", "bye", "and" and "OK". Write a program that finds:

  • the length of the longest word outside the parentheses (print 0, if there is no word outside the parentheses),
  • the number of words inside the parentheses (print 0, if there is no word inside the parentheses).

 Input

The first line of the input contains a single integer n (1 ≤ n ≤ 255) — the length of the given string. The second line contains the string consisting of only lowercase and uppercase English letters, parentheses and underscore symbols.

 Output

Print two space-separated integers:

  • the length of the longest word outside the parentheses (print 0, if there is no word outside the parentheses),
  • the number of words inside the parentheses (print 0, if there is no word inside the parentheses).

 Sample Input

37
_Hello_Vasya(and_Petya)__bye_(and_OK)
37
_a_(_b___c)__de_f(g_)__h__i(j_k_l)m__
27
(LoooonG)__shOrt__(LoooonG)
5
(___)

 Sample Output

5 4
2 6
5 2
0 0

 Hint

In the first sample, the words "Hello", "Vasya" and "bye" are outside any of the parentheses, and the words "and", "Petya", "and" and "OK" are inside. Note, that the word "and" is given twice and you should count it twice in the answer.

 Problem Idea

解題思路:

【題意】

給你一個僅有大小寫字母、下劃線、小括號(小括號不會嵌套)組成的字符串

問括號外單詞的最大長度以及括號內單詞的個數

單詞的定義爲僅有大小寫字母組成

【類型】
模擬題
【分析】

這題只要按照題目要求處理一遍字符串就可以了

可以用flag標記當前位置是括號內還是括號外

在括號內時,可以用is_word標記是否遇到單詞

其他的只要注意細節,一般都不會有問題

【時間複雜度&&優化】
O(strlen(s))

題目鏈接→Codeforces Problem 723B Text Document Analysis

 Source Code

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define eps 1e-9
#define LL long long
#define PI acos(-1.0)
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 300;
const int M = 100005;
const int inf = 1000000007;
const int mod = 101;
char s[N];
int main()
{
    int n,Max,ans,tmp,i;
    bool flag=true,is_word=false;
    scanf("%d",&n);
    scanf("%s",s);
    for(Max=tmp=ans=i=0;s[i]!='\0';i++)
    {
        if(s[i]>='A'&&s[i]<='Z'||s[i]>='a'&&s[i]<='z')
        {
            if(flag)
                tmp++;
            else
                is_word=true;
            continue;
        }
        if(flag)
        {
            Max=max(Max,tmp);
            tmp=0;
        }
        else
        {
            if(is_word)
                ans++;
            is_word=false;
        }
        if(s[i]=='(')
            flag=false;
        else if(s[i]==')')
            flag=true;
    }
    if(flag)
    {
        Max=max(Max,tmp);
        tmp=0;
    }
    else
    {
        if(is_word)
            ans++;
        is_word=false;
    }
    printf("%d %d\n",Max,ans);
    return 0;
}

 Problem C-Polycarp at the Radio

Accept: 0    Submit: 0
Time Limit: 2 seconds    Memory Limit : 256 megabytes

 Problem Description

Polycarp is a music editor at the radio station. He received a playlist for tomorrow, that can be represented as a sequence a1, a2, ..., an, where ai is a band, which performs the i-th song. Polycarp likes bands with the numbers from 1 to m, but he doesn't really like others.

We define as bj the number of songs the group j is going to perform tomorrow. Polycarp wants to change the playlist in such a way that the minimum among the numbers b1, b2, ..., bm will be as large as possible.

Find this maximum possible value of the minimum among the bj (1 ≤ j ≤ m), and the minimum number of changes in the playlist Polycarp needs to make to achieve it. One change in the playlist is a replacement of the performer of the i-th song with any other group.

 Input

The first line of the input contains two integers n and m (1 ≤ m ≤ n ≤ 2000).

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 10^9), where ai is the performer of the i-th song.

 Output

In the first line print two integers: the maximum possible value of the minimum among the bj (1 ≤ j ≤ m), where bj is the number of songs in the changed playlist performed by the j-th band, and the minimum number of changes in the playlist Polycarp needs to make.

In the second line print the changed playlist.

If there are multiple answers, print any of them.

 Sample Input

4 2
1 2 3 2
7 3
1 3 2 2 2 2 1
4 4
1000000000 100 7 1000000000

 Sample Output

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

 Hint

In the first sample, after Polycarp's changes the first band performs two songs (b1 = 2), and the second band also performs two songs (b2 = 2). Thus, the minimum of these values equals to 2. It is impossible to achieve a higher minimum value by any changes in the playlist.

In the second sample, after Polycarp's changes the first band performs two songs (b1 = 2), the second band performs three songs (b2 = 3), and the third band also performs two songs (b3 = 2). Thus, the best minimum value is 2.

 Problem Idea

解題思路:

【題意】

有一個序列a1,a2,…,an

現在定義bj表示數j在序列中出現的次數

問最小值bj(1≤j≤m)的最大可能值爲多少,以及最少需要替換序列中的幾個數

並輸出替換之後的序列a1,a2,…,an

【類型】
貪心
【分析】

首先,我們需要理解的是何爲最小值bj(1≤j≤m)的最大可能值

因爲bj表示數j(1≤j≤m)在序列中出現的次數

而每個數出現的次數一開始是不一定的,這時候會存在一個最小值bj,即出現次數最少的那個數的出現次數

而這個最大可能值的含義是我們要替換一些數,使得出現次數最少的次數儘可能大

例如下面這組數據

6 5

1 2 2 345 2134 885

最開始bj(1≤j≤m)分別爲

  j= 1 2 3 4 5

bj= 1 2 0 0 0

那此時bj最小值爲0,爲了使bj最小值儘可能大,我們需做如下替換:

2->3 345->4 2134->5

這樣之後bj最小值爲1,替換次數爲3

由抽屜原理可知,bj最小值的最大可能值爲n/m

而要使得bj(1≤j≤m)均達到n/m,那就必須將>m的數或是bj>n/m的數替換成bj<n/m的數

這就是貪心的過程

【時間複雜度&&優化】
O(N+M)

題目鏈接→Codeforces Problem 723C Polycarp at the Radio

 Source Code

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define eps 1e-9
#define LL long long
#define PI acos(-1.0)
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 2005;
const int M = 100005;
const int inf = 1000000007;
const int mod = 101;
int s[N],v[N];
int main()
{
    int n,m,i,j,k=0;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&s[i]);
        if(s[i]<=m)
            v[s[i]]++;
    }
    for(j=i=1;i<=n;i++)
    {
        while(j<=m&&v[j]>=n/m)
            j++;
        if(j>m)
            break;
        if(s[i]>m||v[s[i]]>n/m)
        {
            if(s[i]<=m)
                v[s[i]]--;
            s[i]=j,v[j]++,k++;
        }
    }
    printf("%d %d\n",n/m,k);
    for(i=1;i<=n;i++)
        printf("%d%c",s[i],i!=n?' ':'\n');
    return 0;
}

 Problem D-Lakes in Berland

Accept: 0    Submit: 0
Time Limit: 2 seconds    Memory Limit : 256 megabytes

 Problem Description

The map of Berland is a rectangle of the size n × m, which consists of cells of size 1 × 1. Each cell is either land or water. The map is surrounded by the ocean.

Lakes are the maximal regions of water cells, connected by sides, which are not connected with the ocean. Formally, lake is a set of water cells, such that it's possible to get from any cell of the set to any other without leaving the set and moving only to cells adjacent by the side, none of them is located on the border of the rectangle, and it's impossible to add one more water cell to the set such that it will be connected with any other cell.

You task is to fill up with the earth the minimum number of water cells so that there will be exactly k lakes in Berland. Note that the initial number of lakes on the map is not less than k.

 Input

The first line of the input contains three integers n, m and k (1 ≤ n, m ≤ 50, 0 ≤ k ≤ 50) — the sizes of the map and the number of lakes which should be left on the map.

The next n lines contain m characters each — the description of the map. Each of the characters is either '.' (it means that the corresponding cell is water) or '*' (it means that the corresponding cell is land).

It is guaranteed that the map contain at least k lakes.

 Output

In the first line print the minimum number of cells which should be transformed from water to land.

In the next n lines print m symbols — the map after the changes. The format must strictly follow the format of the map in the input data (there is no need to print the size of the map). If there are several answers, print any of them.

It is guaranteed that the answer exists on the given data.

 Sample Input

5 4 1
****
*..*
****
**.*
..**
3 3 0
***
*.*
***

 Sample Output

1
****
*..*
****
****
..**
1
***
***
***

 Hint

In the first example there are only two lakes — the first consists of the cells (2, 2) and (2, 3), the second consists of the cell (4, 3). It is profitable to cover the second lake because it is smaller. Pay attention that the area of water in the lower left corner is not a lake because this area share a border with the ocean.

 Problem Idea

解題思路:

【題意】

n*m的矩形,每個格子不是'*'就是'.','*'代表陸地,'.'代表水

定義湖是有多個相鄰的水組成的(且湖周圍必須是陸地,故與海洋相連的水不能組成湖)

問至少要填補多少個單位的水,才能使得恰好有k個湖

【類型】
模擬+dfs
【分析】

假設最初n*m的矩形中有t個湖

總體來說,出題人還算是人性化的,他的一句話把本題的難度降低了

"Note that the initial number of lakes on the map is not less than k." => t≥k

這句話意味着我們只要將湖面積較小的t-k個湖完全填掉就可以了

而不用填某些格子,使得一個湖分成多個湖

那麼我們需要做的是先一遍dfs將湖的個數找出來,當然,要排除那些與海洋相連接的水

然後將找出的湖丟進優先隊列中,按湖面積從小到大排列

接着就是填補優先隊列中前t-k個湖即可

【時間複雜度&&優化】
O(N×M)

題目鏈接→Codeforces Problem 723D Lakes in Berland

 Source Code

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define eps 1e-9
#define LL long long
#define PI acos(-1.0)
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 55;
const int M = 100005;
const int inf = 1000000007;
const int mod = 101;
char s[N][N];
bool v[N][N],flag;
int ans,n,m,c,g[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
struct node
{
    int x,y,num;
    node(){}
    node(int _x,int _y,int _num):x(_x),y(_y),num(_num){}
    bool operator < (const node &a) const
    {
       return num>a.num;//最小值優先
    }
};
priority_queue<node> q;
void dfs1(int x,int y)
{
    ans++;
    v[x][y]=true;
    for(int i=0;i<4;i++)
    {
        int l=x+g[i][0];
        int r=y+g[i][1];
        if(!v[l][r]&&s[l][r]=='.')
        {
            if(!l||!r||l==n-1||r==m-1)
            {
                flag=false;
                continue;
            }
            dfs1(l,r);
        }
    }
}
void dfs2(int x,int y)
{
    v[x][y]=true;
    s[x][y]='*';
    c++;
    for(int i=0;i<4;i++)
    {
        int l=x+g[i][0];
        int r=y+g[i][1];
        if(!v[l][r]&&s[l][r]=='.')
            dfs2(l,r);
    }
}
int main()
{
    int k,i,j,t=0;
    node u;
    memset(v,false,sizeof(v));
    scanf("%d%d%d",&n,&m,&k);
    for(i=0;i<n;i++)
        scanf("%s",s[i]);
    for(i=1;i<n-1;i++)
        for(j=1;j<m-1;j++)
        {
            if(s[i][j]=='.'&&!v[i][j])
            {
                ans=0;
                flag=true;
                dfs1(i,j);
                if(flag)
                {
                    t++;
                    q.push(node(i,j,ans));
                }
            }
        }
    c=0;
    memset(v,false,sizeof(v));
    while(t>k)
    {
        u=q.top();
        q.pop();
        dfs2(u.x,u.y);
        t--;
    }
    printf("%d\n",c);
    for(i=0;i<n;i++)
        printf("%s\n",s[i]);
    return 0;
}
菜鳥成長記
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章