Codeforces Round #343 (Div. 2) A B C D





链接:戳这里

A. Far Relative’s Birthday Cake
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Door's family is going celebrate Famil Doors's birthday party. They love Famil Door so they are planning to make his birthday cake weird!

The cake is a n × n square consisting of equal squares with side length 1. Each square is either empty or consists of a single chocolate. They bought the cake and randomly started to put the chocolates on the cake. The value of Famil Door's happiness will be equal to the number of pairs of cells with chocolates that are in the same row or in the same column of the cake. Famil Doors's family is wondering what is the amount of happiness of Famil going to be?

Please, note that any pair can be counted no more than once, as two different cells can't share both the same row and the same column.

Input
In the first line of the input, you are given a single integer n (1 ≤ n ≤ 100) — the length of the side of the cake.

Then follow n lines, each containing n characters. Empty cells are denoted with '.', while cells that contain chocolates are denoted by 'C'.

Output
Print the value of Famil Door's happiness, i.e. the number of pairs of chocolate pieces that share the same row or the same column.

Examples
input
3
.CC
C..
C.C


output
4


input
4
CC..
C..C
.CC.
.CC.


output
9


Note
If we number rows from top to bottom and columns from left to right, then, pieces that share the same row in the first sample are:

1. (1, 2) and (1, 3)
2. (3, 1) and (3, 3)


Pieces that share the same column are:


1. (2, 1) and (3, 1)
2. (1, 3) and (3, 3)


题意:问每一行每一列C有多少对


思路:暴力C(n,2)


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
#define INF (1ll<<60)-1
using namespace std;
int n;
int a[110][110];
string s;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>s;
        for(int j=0;j<s.size();j++){
            if(s[j]=='.') a[i][j+1]=0;
            else a[i][j+1]=1;
        }
    }
    int num=0,ans=0;
    for(int i=1;i<=n;i++){
        num=0;
        for(int j=1;j<=n;j++){
            if(a[i][j]==1) num++;
        }
        ans+=(num*(num-1)/2);
    }
    for(int i=1;i<=n;i++){
        num=0;
        for(int j=1;j<=n;j++){
            if(a[j][i]==1) num++;
        }
        ans+=(num*(num-1)/2);
    }
    cout<<ans<<endl;
    return 0;
}


B. Far Relative’s Problem
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Famil Door wants to celebrate his birthday with his friends from Far Far Away. He has n friends and each of them can come to the party in a specific range of days of the year from ai to bi. Of course, Famil Door wants to have as many friends celebrating together with him as possible.

Far cars are as weird as Far Far Away citizens, so they can only carry two people of opposite gender, that is exactly one male and one female. However, Far is so far from here that no other transportation may be used to get to the party.

Famil Door should select some day of the year and invite some of his friends, such that they all are available at this moment and the number of male friends invited is equal to the number of female friends invited. Find the maximum number of friends that may present at the party.

Input
The first line of the input contains a single integer n (1 ≤ n ≤ 5000) — then number of Famil Door's friends.

Then follow n lines, that describe the friends. Each line starts with a capital letter 'F' for female friends and with a capital letter 'M' for male friends. Then follow two integers ai and bi (1 ≤ ai ≤ bi ≤ 366), providing that the i-th friend can come to the party from day ai to day bi inclusive.

Output
Print the maximum number of people that may come to Famil Door's party.

Examples
input
4
M 151 307
F 343 352
F 117 145
M 24 128


output
2


input
6
M 128 130
F 128 131
F 131 140
F 131 141
M 131 200
M 140 200


output
4


Note
In the first sample, friends 3 and 4 can come on any day in range [117, 128].

In the second sample, friends with indices 3, 4, 5 and 6 can come on day 140.


题意:给出每个男女所在的天区间,问哪一天男女人数相等且最多


思路:取每天男女小的个数*2


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
#define INF (1ll<<60)-1
using namespace std;
int n;
char c;
int a[550],b[550];
int main(){
    cin>>n;
    int x,y;
    for(int i=1;i<=n;i++){
        cin>>c;
        cin>>x>>y;
        if(c=='M'){
            for(int j=x;j<=y;j++){
                a[j]++;
            }
        }else{
            for(int j=x;j<=y;j++){
                b[j]++;
            }
        }
    }
    int ans=0,tmp=-1;
    for(int i=1;i<=366;i++){
        ///ans=max(ans,a[i]+b[i]);
        if(ans<min(a[i],b[i])*2){
            tmp=i;
            ans=min(a[i],b[i])*2;
        }
    }
    ///cout<<tmp<<" "<<ans<<endl;
    cout<<ans<<endl;
    return 0;
}


C. Famil Door and Brackets
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
As Famil Door’s birthday is coming, some of his friends (like Gabi) decided to buy a present for him. His friends are going to buy a string consisted of round brackets since Famil Door loves string of brackets of length n more than any other strings!

The sequence of round brackets is called valid if and only if:

the total number of opening brackets is equal to the total number of closing brackets;
for any prefix of the sequence, the number of opening brackets is greater or equal than the number of closing brackets.
Gabi bought a string s of length m (m ≤ n) and want to complete it to obtain a valid sequence of brackets of length n. He is going to pick some strings p and q consisting of round brackets and merge them in a string p + s + q, that is add the string p at the beginning of the string s and string q at the end of the string s.

Now he wonders, how many pairs of strings p and q exists, such that the string p + s + q is a valid sequence of round brackets. As this number may be pretty large, he wants to calculate it modulo 109 + 7.

Input
First line contains n and m (1 ≤ m ≤ n ≤ 100 000, n - m ≤ 2000) — the desired length of the string and the length of the string bought by Gabi, respectively.

The second line contains string s of length m consisting of characters '(' and ')' only.

Output
Print the number of pairs of string p and q such that p + s + q is a valid sequence of round brackets modulo 109 + 7.

Examples
input
4 1
(


output
4


input
4 4
(())


output
1


input
4 3
(((


output
0


Note
In the first sample there are four different valid pairs:

p = "(", q = "))"
p = "()", q = ")"
p = "", q = "())"
p = "", q = ")()"


In the second sample the only way to obtain a desired string is choose empty p and q.

In the third sample there is no way to get a valid sequence of brackets.


题意:给出n表示设计出来的字符串长度为n,给出m表示一个长度为m的字符串(     只存在'('和')'      )。接着一个长度为m的字符串s。设计的长度为n的字符串为p+s+q   问p,q有多少种情况是满足条件

满足的条件是整段p+s+q串的当前的'('数量必须>=当前的')'数量  必须'('')'匹配


思路:首先我们拿p q分别去填s的左边和s的右边,我们要知道中间的s的'('和')'的情况。这个先放这里

很容易想到dp[i][j]  状态表示为当前长度为i且平衡度为j的种数。这个平衡度的定义是当前的i左边的'('减去左边的')'的值,我们必须要保证左边的'('一定要>=左边的')' 

好 接下来推理dp[i][j]的转移

首先当前长度i是由i-1的哪些状态推来的呢?

有两种 ,第一是当前dp[i][j]    j的平衡度情况下dp[i-1][?]   

 i位置上是'('  那么dp[i][j]+=dp[i-1][j-1]

 i位置上是')'  那么dp[i][j]+=dp[i-1][j+1]  

状态转移推出来之后直接0 ((n-m)*(n-m))求出答案   这里需要注意一开始所提到的问题,s的'('和')'的情况

然后枚举每一个i当做p结尾的情况去累加种数求出答案


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
#define mod 1000000007
using namespace std;
ll dp[2010][2010];
string s;
int n,m;
int main(){
    mst(dp,0);
    scanf("%d%d",&n,&m);
    cin>>s;
    dp[0][0]=1;
    for(int i=1;i<=n-m;i++){
        dp[i][0]=dp[i-1][1]%mod;
        for(int j=1;j<=i;j++){
            dp[i][j]=(dp[i-1][j-1]+dp[i-1][j+1])%mod;
        }
    }
    int mn=maxn,sum=0;
    for(int i=0;i<s.size();i++){
        if(s[i]=='(') sum++;
        else sum--;
        mn=min(mn,sum);
    }
    ll ans=0;
    for(int i=0;i<=n-m;i++){
        for(int j=0;j<=i;j++){
            if(j+mn>=0 && j+sum<=n-m-i){
                ans+=(dp[i][j]*dp[n-m-i][j+sum])%mod;
                ans%=mod;
            }
        }
    }
    printf("%I64d\n",ans%mod);
    return 0;
}



D. Babaei and Birthday Cake
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
As you know, every birthday party has a cake! This time, Babaei is going to prepare the very special birthday party's cake.

Simple cake is a cylinder of some radius and height. The volume of the simple cake is equal to the volume of corresponding cylinder. Babaei has n simple cakes and he is going to make a special cake placing some cylinders on each other.

However, there are some additional culinary restrictions. The cakes are numbered in such a way that the cake number i can be placed only on the table or on some cake number j where j < i. Moreover, in order to impress friends Babaei will put the cake i on top of the cake j only if the volume of the cake i is strictly greater than the volume of the cake j.

Babaei wants to prepare a birthday cake that has a maximum possible total volume. Help him find this value.

Input
The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of simple cakes Babaei has.

Each of the following n lines contains two integers ri and hi (1 ≤ ri, hi ≤ 10 000), giving the radius and height of the i-th cake.

Output
Print the maximum volume of the cake that Babaei can make. Your answer will be considered correct if its absolute or relative error does not exceed 1e-6.

Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .

Examples
input
2
100 30
40 10


output
942477.796077000


input
4
1 1
9 7
1 4
10 7


output
3983.539484752


Note
In first sample, the optimal way is to choose the cake number 1.

In second sample, the way to get the maximum volume is to use cakes with indices 1, 2 and 4.


题意:给出n个圆柱体蛋糕  体积为a[i]=h[i]*r[i]*r[i]*PI,然后按照(1~n)的顺序去选择性的叠蛋糕,要求选出来的蛋糕叠出来的体积最大


思路:很好想到是求最大的上升子序列和

首先我们可以想到O(n*n)的思路,枚举每一个i   dp[i]表示当前所有的蛋糕叠到i的最大值

再去枚举(1~i-1)内的最大的dp[j],并判断a[i]是否大于a[j],大于就加上当前的a[i],否则反之,再更新dp[i]的值

会超时,我们需要想办法把从(1~i-1)找最大的dp[j]的复杂度将为logn,一般区间上的操作基本都想到线段树

我们需要用线段树在区间(1~i-1)上找出最大dp[j],但是由于这段区间上的值是乱序的,线段树是从小到大的。怎么处理呢?

想到离散化,a[i]排序之后记录每个i相对之前的下标。然后根据下标我们可以查询【1,下标】上的已经存进线段树的最大值dp[j],然后又因为a[i]是排序的所以直接加  dp[i]=dp[j]+a[i]

但是我们忽略了一个问题,因为里面会有相等的a[i],而我们要求是严格大于,怎么办?我们需要找到a数组中的第一个>=当前值的下标然后去线段树找出【1,下标】的最值   用  num[i]=lower_bound(a+1,a+n+1,v[i])-a;  之前一直错这里


代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const long double pi=acos(-1.0);
int n;
ll dp[100100];
ll tr[400100];
int num[100100];
ll a[100100],v[100100];
void build(int root,int l,int r){
    if(l==r) {
        tr[root]=0;
        return ;
    }
    int mid=(l+r)/2;
    build(root*2,l,mid);
    build(root*2+1,mid+1,r);
    tr[root]=max(tr[root*2],tr[root*2+1]);
}
ll query(int root,int l,int r,int x,int y){
    if(l>=x && r<=y) return tr[root];
    int mid=(l+r)/2;
    if(x>mid) return query(root*2+1,mid+1,r,x,y);
    else if(y<=mid) return query(root*2,l,mid,x,y);
    else {
        return max(query(root*2,l,mid,x,mid),query(root*2+1,mid+1,r,mid+1,y));
    }
}
void update(int root,int l,int r,int x,ll v){
    if(l==r){
        tr[root]=v;
        return ;
    }
    int mid=(l+r)/2;
    if(x<=mid) update(root*2,l,mid,x,v);
    else update(root*2+1,mid+1,r,x,v);
    tr[root]=max(tr[root*2],tr[root*2+1]);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        int r,h;
        scanf("%d%d",&r,&h);
        a[i]=(ll)r*r*h;
        v[i]=a[i];
    }
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++) num[i]=lower_bound(a+1,a+n+1,v[i])-a;
    /// 在a数组中找出第一个>=v[i]的数的下标
    build(1,1,n);
    for(int i=1;i<=n;i++){
        if(num[i]==1) dp[i]=a[num[i]];
        else dp[i]=query(1,1,n,1,num[i]-1)+a[num[i]];
        update(1,1,n,num[i],dp[i]);
    }
    ll ans=0;
    for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
    long double t=pi*ans;
    cout<<setprecision(20)<<t<<endl;
    return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值