Codeforces Round #FF (Div. 2)(A-D 未完)

来源:互联网 发布:微商城源码 编辑:程序博客网 时间:2024/05/01 08:44

A. DZY Loves Hash

题意:给你n个数字,对他们进行hash,hash的具体操作就是就是把他们放到m个数组里面,比如x放到第x%m+1个数组里面,问是否会有冲突,有输出第几个最先出现冲突,没有输出-1
思路:简单模拟

代码:

#include<bits/stdc++.h>using namespace std;int a[310];int main(){    int n,m;    scanf("%d%d",&n,&m);    memset(a,0,sizeof(a));    bool judge=false;    for(int i=0;i<m;i++){        int temp;        scanf("%d",&temp);        if(judge)             continue;        if(a[temp%n]){            printf("%d\n",i+1);            judge=true;        }        else{            a[temp%n]=1;        }    }    if(!judge)        printf("-1\n");}

B. DZY Loves Strings

题意:给你一个字符串,让你在最后补充n个字母,同时a-z每个字母都有自己的价值,问,在原字符串的基础上,补充了n个字母以后,整个字符串最大价值是多少
思路:简单贪心,补充的都是价值最大的即可

代码:

#include<bits/stdc++.h>using namespace std;int a[26];int main(){    char b[1010];    scanf("%s",b);    int n;    scanf("%d",&n);    for(int i=0;i<26;i++)        scanf("%d",&a[i]);    int x=strlen(b);    int val=0;    for(int i=0;i<x;i++){        int temp=b[i]-'a';        val+=(i+1)*a[temp];    }    int maxn=a[0];    for(int i=1;i<26;i++)        maxn=max(maxn,a[i]);    for(int i=0;i<n;i++)        val+=(i+1+x)*maxn;    printf("%d\n",val);}

C. DZY Loves Sequences

题意:给你一个数列,现在允许你改变最多一个数字,问能够最长多少连续上升的子序列
思路:预处理,我们可以先预处理出来之前包含第i个数字的最长连续上升子序列和之后包含第i个数字的最长连续上升子序列,然后,我们就可以处理这个数列,对于第i个数字,如果第i+1个数字减去第i-1个数字的值大于1,那么我们就可以利用i将i-1和i+1这两部分连起来,如果第i+1个数字减去第i-1个数字的值不大于1,那我们只能改变i使得i-1和i+1的部分分别+1了,然后在这个过程寻找最大值就好了

代码:

#include<bits/stdc++.h>using namespace std;const int maxn= 1e5+10;int a[maxn];int c[maxn];int d[maxn];int main(){    int n;    scanf("%d",&n);    for(int i=0;i<n;i++)        scanf("%d",&a[i]);    memset(c,0,sizeof(c));    memset(d,0,sizeof(d));    c[0]=1;    for(int i=1;i<n;i++)    {        if(a[i]>a[i-1])            c[i]=c[i-1]+1;        else            c[i]=1;    }    d[n-1]=1;    for(int i=n-2;i>=0;i--){        if(a[i]<a[i+1])            d[i]=d[i+1]+1;        else            d[i]=1;    }    int ans=max(d[1]+1,c[n-2]+1);    for(int i=1;i<n;i++){        if(a[i+1]-a[i-1]>1)        {            ans=max(ans,c[i-1]+1+d[i+1]);        }        else{            ans=max(ans,c[i-1]+1);            ans=max(ans,d[i+1]+1);        }    }    printf("%d\n",ans);}

D - DZY Loves Modification

题意:给你一个矩阵,现在进行k次操作,第一种是选择某一行,让这行都减去q,另一种操作是选某一列,让这一列都减去q,这两种操作,都能获得操作之前的这行(列)所有值的和,问经过k次操作后,最多能获得多少值
思路:思维+预处理+优先队列,首先,我们不管在选择行还是列,肯定是优先选择最大的,而我们选择了x行,就会选择k-x列,然后,我们每次选一行进行操作,这个操作对于每一列的影响都是一样的,而我们选列时也是同理,所以,我们选择行时,是不会影响到列的选择的,可是,不会影响列的选择,但是会影响到列选择后的数值,我们通过画图,能发现,假如我们选择x列,k-x行,那么我们每行产生的影响就是q*(k-x),一共x行,就产生了x*q*(k-x)的影响,然后,我们只需要预处理出选择1-k个行(列)时候的数值,就能通过枚举行数,得到对应列数,同时得到对应影响数值,这样就能得到每种情况下的最后的答案了

代码:

#include<bits/stdc++.h>using namespace std;long long a[1010][1010];long long b1[1010000],b2[1010000];int n,m,k,p;priority_queue<long long> q1;priority_queue<long long> q2;int main(){    scanf("%d%d%d%d",&n,&m,&k,&p);    for(int i=0;i<n;i++)        for(int j=0;j<m;j++)            scanf("%I64d",&a[i][j]);    for(int i=0;i<n;i++){        long long temp=0;        for(int j=0;j<m;j++)            temp+=a[i][j];        q1.push(temp);    }    for(int i=0;i<m;i++)    {        long long temp=0;        for(int j=0;j<n;j++)            temp+=a[j][i];        q2.push(temp);    }    b1[0]=b2[0]=0;    for(int i=1;i<=k;i++){        long long temp=q1.top();            b1[i]=b1[i-1]+temp;        q1.pop();        q1.push(temp-(long long)m*p);    }    for(int i=1;i<=k;i++){        long long temp=q2.top();            b2[i]=b2[i-1]+temp;        q2.pop();        q2.push(temp-(long long)n*p);    }    long long ans=(long long)b2[k];    for(int i=1;i<=k;i++){        ans=max(ans,(long long)b1[i]+(long long)b2[k-i]-(long long)(i)*p*(k-i));    }    printf("%I64d\n",ans);}

原创粉丝点击