Deltix Round, Autumn 2021 (open for everyone, rated, Div. 1 + Div. 2)

1,A. Divide and Multiply-Deltix Round, Autumn 2021 (open for everyone, rated, Div. 1 + Div. 2)

题意:n个整数组成的数组。选择两个任意不相同的元素a,b,使a/2,b * 2.(a必须使2的倍数)可以进行上面的操作任意次数,求经 过操作后的数组的所有元素的乘积最大是多少。

题解:num=0。从第一个元素开始,如果取余2等于零,就将该数除2,并且num++。将进行操作过的数组进行排序,找到最大的元素, 并且乘num次2,并输出。

解释:奇数没有办法除2只能用来乘。一个偶数可以看成是以及操作过的多个2乘一个奇数(比如8就是3个2乘1),把所有的2都提取出 来,最后都乘到一个最大的奇数上去就可以了。
代码:

#include<iostream>
#include<algorithm>
 
using namespace std;
#define ll long long 
ll n,m;
ll a[20]; 
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
    cin >> n;
    ll sum=0,i2; 
    for(int i1=1;i1<=n;i1++)
    cin >> a[i1];
    sort(a+1,a+1+n);
    i2=0;
    for(int i1=1;i1<=n;i1++)
    {
    while(a[i1]>=2&&a[i1]%2==0) {sum++;a[i1]/=2;}
    }
    sort(a+1,a+n+1);
    for(m=1;m<=sum;m++) a[n]*=2;
    sum=0;
    for(m=1;m<=n;m++) sum+=a[m];
    cout <<sum<< endl;
    }
    return 0;
}

2,B. William the Vigilant-Deltix Round, Autumn 2021 (open for everyone, rated, Div. 1 + Div. 2)

题意:给出n,m和一个字符串s。n是字符串的长度,m是问题的数量。每个问题有两个参数,k,c,意思是把x中第k个字符换成c。每 个问题输出一个答案ans。ans表示x中abc子串的数量。

题解:首先求出原字符串x中abc子串的数量num。当输入每个问题的时候,先判断是否替换值和被替换值相等,如果相等,直接输出 num。不相等,判断被替换的字符是子串abc中的一个(如何判断看解释),如果是则num++输出。如果不是则判断是否替换后能够形 成一个abc子串。

解释:判断原字符是abc子串中的一个,有三个if语句,x[k-3]= =‘a’&&x[k-2]= =‘b’&&x[k-1]= =‘c’ ,x[k-2]= =‘a’&&x[k-1]= =‘b’&&x [k]= =‘c’,x[k-1]= =‘a’&&x[k]= =‘b’&&x[k+1]= =‘c’。判断形成新的abc子串也有三个if,x[k-3]= =‘a’&&x[k-2]= =‘b’&&x[k-1]= =‘c’ ,x[k-2]= =‘a’&&x[k-1]= =‘b’&&x[k]= =‘c’,x[k-1]= =‘a’&&x[k]= =‘b’&&x[k+1]==‘c’。因为abc子串是互相独立的,所以增加或者是 减少一个对后面的无影响。
代码:

/**
 *@author wrcccccccc 
 */
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
 
using namespace std;
 
string x,y="abc";
int n,m;
int f()
{
    int i1,i2;
    int ans=0;
//    cout<<x<<endl;
    if(x.size()<=2) return ans;
    for(i1=0;i1<x.size()-2;i1++)
    {
        if(x[i1]=='a'&&x[i1+1]=='b'&&x[i1+2]=='c') {ans++;i1+=2;}
    }
    return ans;
}
int main()
{
//    freopen("1.txt","r",stdin);
    int i1,i2,i3,i4,i5;
    int k;
    cin>>n>>m;
    cin>>x;
    char c;
   i2=f();
    for(i1=1;i1<=m;i1++)
    {
        scanf("%d %c",&k,&c);
        if(x[k-1]==c) {printf("%d\n",i2);continue;}
        else if(x[k-3]=='a'&&x[k-2]=='b'&&x[k-1]=='c') i2--;
        else if(x[k-2]=='a'&&x[k-1]=='b'&&x[k]=='c') i2--;
        else if(x[k-1]=='a'&&x[k]=='b'&&x[k+1]=='c') i2--;
        
        x[k-1]=c;
        if(x[k-3]=='a'&&x[k-2]=='b'&&x[k-1]=='c') i2++;
        else if(x[k-2]=='a'&&x[k-1]=='b'&&x[k]=='c') i2++;
        else if(x[k-1]=='a'&&x[k]=='b'&&x[k+1]=='c') i2++;
        
        printf("%d\n",i2);
    }
    return 0;
}

3,C. Complex Market Analysis-Deltix Round, Autumn 2021 (open for everyone, rated, Div. 1 + Div. 2)

题意:有n个整数的数组并且给出参数值e,问有多少个(i,k)组合,使得1,i和k>=1,2,i+ek<=n,3,aiai+e*ai+2e…*ai+ke是也 一个质数。

题解:ans=0。首先知道题目中元素个范围是1e6之内的,找出1e6内的所有质数。从一个元素开始找到是质数的值停止,令num=1,向 前每次加e找值为1的元素,如果找到ans++并且num++,如果不为1则退出。同样的向后找,每次减e,但是如果是1每次ans+=num,不 为1则退出。

解释,例如1,1,1,3其实也算,但是前面有两个1,如果每一个数都向后找到最后的话会超时,但是从质数出发就可以减小运算的次 数。
代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <math.h>
 
using namespace std;
const int Maxsize=1000005;
int flag1[Maxsize+20],a[Maxsize+20];
int temp[Maxsize+20];
long long n,m,e,ans;
 
void f(int x)
{
    int i1,i2,i3,i4;
    if(flag1[a[x]]==1) return ;
    long long num=0;
    for(i1=x+e;i1<=n;i1+=e)
    {
        if(a[i1]==1)
            {
                ans++;
                num++;
 
            }
        else break;
    }
    num++;
    for(i1=x-e;i1>=1;i1-=e)
    {
        if(a[i1]==1)
        {
                ans+=num;
 
        }
        else break;
    }
    return ;
}
int main()
{
    //freopen("3.txt","r",stdin);
    int i1,i2,i3,i4,i5;
    for(i1=2;i1<=sqrt(Maxsize);i1++)
        if(flag1[i1]!=1)
            for(i2=2;i2*i1<=Maxsize;i2++)
            {
                flag1[i2*i1]=1;
            }
    flag1[1]=1;
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%d%d",&n,&e);
        for(i1=1;i1<=n;i1++)
            scanf("%d",&a[i1]);
        ans=0;
        for(i1=1;i1<=n;i1++)
        {
            f(i1);
        }
        cout<<ans<<endl;
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值