CodeCraft-19 and Codeforces Round #537 (Div. 2)

A. Superhero Transformation

水题,注意两个字符串可能长度不相等。

#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=100010;
map<char ,int >m;
int main(){
    m[‘a‘]=m[‘e‘]=m[‘i‘]=m[‘o‘]=m[‘u‘]=1;
    string s1,s2;
    while(cin>>s1>>s2)
    {
        int flag=1;
        if(s1.length()!=s2.length())flag=0;
        for(int i=0;i<s1.length();i++)
        {
            if(m[s1[i]]!=m[s2[i]]){
                flag=0;
                break;
            }
        }
        if(flag)puts("Yes");
        else puts("No");
    }
} 

B. Average Superhero Gang Power

题意:有n个人,每个人都有权值,然后你有m次操作,每次操作可以删掉一个人或者给一个人的权值加一,使得最后剩下的人平均数最大。

坑爹题,后台数据太水了,一开始以为只要删的剩下权值最大的那个一人,然后全加加给这个人就好了,居然过了。

一个半小时后被hack(感谢大哥比赛中hack的我,否则要掉分了),发现比如一组样例如果全是“7 7 7 7 7”这样的就会错,因为删人不一定是最好的选择,所以就枚举删几个人,然后取最大值就好了。

比赛刚结束我的rank1200+,rejudge后变600+,新年惨案哈哈哈。

#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=100010;
double a[maxn],b[maxn];
int n,m,k;
int main(){
    while(cin>>n>>k>>m)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%lf",&a[i]);
        }
        sort(a+1,a+1+n);
        for(int i=1;i<=n;i++)
        {
            b[i]=b[i-1]+a[i];
        }
        double ans=0;
        double tot,po;
        for(int i=0;i<=m&&i<=n-1;i++)
        {
            tot=b[n]-b[i];
            po=n-i;
            if(i<m)
            tot+=min(po*k,(double)m-i);
            ans=max(ans,tot/po);
        }
        printf("%.8f\n",ans);
    }
} 

C. Creative Snap

题意:有2^n个格子,格子可能是空的,也可能站着许多人,有两种操作。操作一是把某一列格子平均分成两部分,操作二是把某一列格子摧毁,如果这一列格子上没有人,那么就需要耗费A的代价,如果格子上有na个人,那么就要耗费B*na*l 的代价,问把所有格子全部摧毁的最小代价是啥。

思路:一开始完全没思路,想了很久,有人说暴力递归可以过,然后就。。试了一下?真的过了,AC后想了一下合法性。

有一个很显然的性质,就是如果一列格子全是空的,那么必定直接付出A的代价进行摧毁,如果有人的话,就要进行考虑。但是发现最多只有k个人,也就是需要考虑的次数不会太多,所以递归并不是nlogn(n=2^30),而是klogk?

#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=100010;
int n,k;
ll A,B;
ll a[maxn];
ll dfs(ll l,ll r){
    ll val=upper_bound(a,a+k,r)-lower_bound(a,a+k,l);
    if(val==0) return A;
    if(l==r) return val*B;
    ll mid=(l+r)>>1;
    ll left=dfs(l,mid),right=dfs(mid+1,r);
    return min(left+right,(val)*B*(r-l+1));
}
int main(){
    while(cin>>n>>k>>A>>B)
    {
        for(int i=0;i<k;i++)
        {
            scanf("%lld",&a[i]);
        }
        sort(a,a+k);
        ll ans=dfs(1,(ll)pow(2,n));
        printf("%lld\n",ans);
    }
} 

D. Destroy the Colony

补。

题意:

  给出一列大小写都有的字符串,字符串长度为偶数,每种字符代表一种人,给出q次查询,每次查询,都是讲所有人分成两部分序列,第x个字符代表的人和第y个字符代表的人要在同一个序列里面,问这样的方案数有多少。序列内排列不同则方案不同,两个序列顺序不同则方案不同。

思路:

  设将字符串合法的分成两部分的方案数是 f 。每个字符的数量是ci,n为字符串长度,m=n/2。

  则答案应该是((m)! *  (m)!  *f *2)/(  ci!   *cj !*……    )

  我们发现这个式子里只有f是不知道的,f等于把x和y放入一个大小为m的背包的方案数。

  如果直接证明做,时间复杂度会超时,所以我们先计算出,所有的n/2大小背包的方案数,如果我们此时把x和y的物品全部从这个背包中减去,就得到了不含x和y的背包的方案数,这个方案数和含xy是一样的。每次减完后再加回去。

  而对于x和y相等的情况下,n/2的背包要么含x,要么不含x,所以此时背包数就等于f*2.

  注意背包如果为空,则不要处理,否则会出错,加减的顺序也要注意。

#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=100010;
const ll p=1e9+7;
int n,m;
char s[maxn];
ll bur[60];
ll fac[maxn],inv[maxn],ans[100][100],dp[maxn],tep[maxn];
int find(char c){
    if(c>=‘A‘&&c<=‘Z‘)return c-‘A‘+26;
    return c-‘a‘;
}
void init(){
    clr(bur,0),clr(dp,0),clr(inv,0);
}
ll qpow(ll a,ll b){
    a%=p;
    ll res=1;
    while(b){
        if(b&1)res*=a;
        res%=p;
        a*=a,a%=p;
        b>>=1;
    }
    return res;
}
int main(){
    while(scanf("%s",s+1)!=EOF)
    {
        init();
        n=strlen(s+1);
        for(int i=1;i<=n;i++)
        {
            bur[find(s[i])]++;
        }
        fac[0]=1;
        for(int i=1;i<=n;i++)
        {
            fac[i]=i*fac[i-1]%p;
        }
        ll num=fac[n/2]*fac[n/2]%p;
        for(int i=0;i<52;i++)
        {
            if(bur[i]==0)continue;
            inv[i]=qpow(fac[bur[i]],p-2);
            num=num*inv[i]%p;
        }
        // printf("num:%lld\n",num);
        dp[0]=1;
        for(int i=0;i<52;i++)
        {
            if(!bur[i])continue;
            for(int j=n/2;j>=bur[i];j--)
            {
                dp[j]+=dp[j-bur[i]];
                dp[j]%=p;
            }
        }
        for(int i=0;i<52;i++)
        {
            ans[i][i]=dp[n/2];
        }
        for(int i=0;i<52;i++)
        {
            if(!bur[i])continue;
            for(int j=0;j<=n/2;j++)tep[j]=dp[j];
            for(int j=bur[i];j<=n/2;j++)
            {
                tep[j]=(tep[j]-tep[j-bur[i]]+p)%p;
            }
            for(int k=i+1;k<52;k++)
            {
                if(!bur[k])continue;
                for(int j=bur[k];j<=n/2;j++)
                {
                    tep[j]=(tep[j]-tep[j-bur[k]]+p)%p;
                }
                ans[i][k]=ans[k][i]=tep[n/2]*2%p;
                for(int j=n/2;j>=bur[k];j--)
                {
                    tep[j]=(tep[j]+tep[j-bur[k]])%p;
                }

            }
        }
        cin>>m;
        int x,y;
        while(m--)
        {
            scanf("%d%d",&x,&y);
            x=find(s[x]),y=find(s[y]);
            printf("%lld\n",num*ans[x][y]%p);
        }
    }

}

E. Tree

待补。

原文地址:https://www.cnblogs.com/mountaink/p/10351663.html

时间: 2024-08-30 07:45:48

CodeCraft-19 and Codeforces Round #537 (Div. 2)的相关文章

CodeCraft-19 and Codeforces Round #537 (Div. 2) - D. Destroy the Colony(动态规划+组合数学)

Problem  CodeCraft-19 and Codeforces Round #537 (Div. 2) - D. Destroy the Colony Time Limit: 2000 mSec Problem Description Input Output For each question output the number of arrangements possible modulo 10^9+7. Sample Input abba21 41 2 Sample Output

CodeCraft-19 and Codeforces Round #537 (Div. 2) A - Superhero Transformation

题目描述 We all know that a superhero can transform to certain other superheroes. But not all Superheroes can transform to any other superhero. A superhero with name ss can transform to another superhero with name tt if ss can be made equal to tt by chan

CodeCraft-19 and Codeforces Round #537 (Div. 2) B. Average Superhero Gang Power

题目描述: Every superhero has been given a power value by the Felicity Committee. The avengers crew wants to maximize the average power of the superheroes in their team by performing certain operations. Initially, there are nn superheroes in avengers tea

[codeforces]Round #537 (Div. 2)E. Tree

题解:  q次查询每次查询k个点  k的总和不超过1e5  那就->虚树  这个题分为两部分  前面先对每次查询的点建虚树 其次计数  对于新树上的每个关键点(查询点)  他能影响的m的范围 必然大于以r为根的祖先节点的个数 然后我们单独考虑每个节点的贡献为 当前集合个数减去其祖先节点的个数  然后我们考虑把每个点按照dfs序的下标考虑贡献  转移分为两部分 1.当前元素加入直接构成一个新集合 2,当前元素加入可以加入到  m(当前集合个数)-祖先节点个数 #include <bits/std

【CodeCraft-19 and Codeforces Round #537 (Div. 2) C】Creative Snap

[链接] 我是链接,点我呀:) [题意] 横坐标1..2^n对应着2^n个复仇者的基地,上面有k个复仇者(位置依次给出). 你是灭霸你要用以下方法消灭这k个复仇者: 一开始你获取整个区间[1..2^n] 假设你当前获取的区间为[l,r] mid = (l+r)/2 那么你每次有两种选择 1.将整个区间全都毁掉,如果这个区间里没有复仇者,那么花费为A,否则花费为B复仇者个数区间长度 2.将区间分为[l,mid]和[mid+1,r]分开毁掉(即分别获取[l,mid]和[mid+1,r]这两个区间,然

CodeCraft-19 and Codeforces Round #537 (Div. 2) 题解

传送门 D. Destroy the Colony 首先明确题意:除了规定的两种(或一种)字母要在同侧以外,其他字母也必须在同侧. 发现当每种字母在左/右边确定之后,方案数就确定了,就是分组的方案数乘\(\frac{((n/2)!)^2}{\prod cnt_i!}\). 分组的方案数考虑DP,设\(dp_{i,j}\)为前\(i\)个字母,占了左边\(j\)个位置的方案数,则有: \[ dp_{i,j}=dp_{i-1,j-cnt_i}+dp_{i-1,j} \] 当\(i\)是指定字母时特判

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd