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

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);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值