Educational Codeforces Round 65 (Rated for Div. 2) A-F

A. Telephone Number
题意:随便删看是否能找到开头为8且长度为11的串

思路:贪心,从前面极限开删找到第一个8的位置后,算一下能否满足长度>=11,感觉我比赛的时候讨论复杂了,算了不管了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#define ll long long
using namespace std;
char s[110];
int main()
{ 
    int t;
    cin>>t;
    while(t--)
    {
       int n;
       scanf("%d",&n);
       scanf("%s",s+1);
       int flag=0;
       for(int i=1;i<=n;++i)
        {
            if(s[i]=='8')
            {
               flag=i;
               break; 
            }
        }
       if(n<11)
       {
          puts("NO");
          continue; 
       } 
       else if(n==11)
       {
          if(s[1]=='8')
          {
             puts("YES");
             continue; 
          } 
          else { 
              puts("NO");
              continue;
          }
       }
       else if(n>11)
       {
          if(!flag)
          {
             puts("NO");
             continue; 
          } 
          else
          {
             if(n-flag+1<11)
             {   
                 puts("NO"); 
                 continue;
             }
             else
             {
                puts("YES");
                continue; 
             }
          }
       }
    }
    return 0;
}

B.Lost Numbers
题解:
较水的交互题,直接1、2,2,3,…判断四次,然后全排列一下6!可秒

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#define ll long long

using namespace std;
int a[10]={4,8,15,16,23,42},d[5];
int main()
{ 
    for(int i=1;i<=4;++i)
    {
       printf("? %d %d\n",i,i+1);
       fflush(stdout);
       scanf("%d",&d[i]); 
    }
    do{ 
        if(a[1]*a[0]==d[1]&&a[2]*a[1]==d[2]&&a[3]*a[2]==d[3]&&a[3]*a[4]==d[4])
            break;
    }while(next_permutation(a,a+6));
    printf("!");
    for(int i=0;i<6;++i)
        printf(" %d",a[i]);
    fflush(stdout);
    return 0;
}

C. News Distribution
题解:并查集模板,没啥好说的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#define ll long long

using namespace std;
const int maxn=5e5+10;
int fa[maxn],size[maxn];
int find(int x)
{
   if(x==fa[x])return x;
   return fa[x]=find(fa[x]);
}
void merge(int x,int y)
{
   x=find(x);
   y=find(y);
   if(x==y)return;
   if(size[x]<size[y])
      swap(x,y);
   fa[y]=x;
   size[x]+=size[y]; 
}
int main()
{ 
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)
    {
       fa[i]=i;
       size[i]=1; 
    }
    int k,a,b;
    for(int i=1;i<=m;++i)
    {
        scanf("%d",&k);
        if(!k)continue;
        scanf("%d",&a);
        for(int i=1;i<k;++i)
        {
           scanf("%d",&b);
           merge(a,b); 
        }
    }
    for(int i=1;i<=n;++i)
        printf("%d ",size[find(i)]);
    return 0;
}

D. Bicolored RBS
题解:贪心,为了保证深度最小,每次遇到一个左括号就分别分配,遇到一次右括号就分配给最近的左括号

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#define ll long long

using namespace std;
const int maxn=2e5+10;
char s[maxn];
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",s);
    int flag=0;
    int len=strlen(s);
    for(int i=0;i<len;++i)
    {
       if(s[i]=='(')
       {
          flag++;
          cout<<flag%2; 
       } 
       else{ 
        cout<<flag%2;
        flag--;
       }
    }
    return 0;
}

E. Range Deleting
题意:多少个f(l,r)使得删去数列中[l,r]的所有数后满足不下降序列

题解:debug了一小时,首先想到暴力枚举,即f(1,x1),f(2,x2),xi表示当前满足的最小的,容易发现,如果f(1,x1)也满足,则有单调性,f(1,x1+1)…f(1,x)也满足
所以总共有(x-x1+1)+(x-x2+1)…
那么怎么迅速求出xi呢

维护四个数组,l[i]表示i的第一个位置,r[i]表示i的最后一个位置,l1[i]表示[i,n]中数字在最前面的位置,r[i]表示[1,n]中数字最后一个位置

所以先用dp思想预处理所有数组,然后找到最小的x1,再用x1递推出剩余的xi,怎么递推呢,就是先在满足[1,i-1]不下降的情况下,再慢慢把x1往后递推直到也满足[1,i-1]与[x1+1,n]组合后不下降,也是dp思想

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#define ll long long

using namespace std;
const int maxn=1e6+10;
int n,x,l[maxn],r[maxn],l1[maxn],r1[maxn],a[maxn];
//[i,n]最前面的pos [1,i]最后的位置
int main()
{ 
    scanf("%d%d",&n,&x);
    for(int i=1;i<=n;++i)
        scanf("%d",&a[i]);
    memset(l,0x3f,sizeof(l));
    for(int i=1;i<=n;++i)
    {
       l[a[i]]=min(i,l[a[i]]);
       r[a[i]]=i; 
    }
    memset(l1,0x3f,sizeof(l1));
    for(int i=x;i>=1;--i)
        l1[i]=min(l1[i+1],l[i]);		//dp预处理
    for(int i=1;i<=x;++i)
        r1[i]=max(r1[i-1],r[i]);
    int m=x;
    //[m,x]非递减
    for(;m>1&&r[m]<=l1[m+1];--m);//找最小的x1

    ll ans=x-m+1;
    //[1,i-1],[m+1,x]满足
    for(int i=2;i<=x&&r1[i-2]<=l[i-1];++i)//[1,i-1]要满足
    {
       for(;m<i||r1[i-1]>l1[m+1];++m);//一直递推直到第一个m
       ans+=x-m+1; 
    }
    printf("%lld\n",ans);
    return 0;
}

F. Scalar Queries
题解:
看了很久才看懂的一道题,首先不难化简到 f(l,r)为a[i]*他在[l,r]中的区间第几小

**面对这种从区间到点的问题,如果很难考虑,应转化为从点转换到区间,考虑每个点的贡献,**首先,每个点的贡献是来自于其左边和右边某个比它小的数aj,

ai与aj,同时包含他们的每个区间会使a[i]*sum[i]中的sum[i]+1,这样就成功把区间排序改变,变成统计该数左边和右边每个比他小的数所贡献的所有区间总数,引用一下他人的话就是,

在这里插入图片描述
所以我们可以用树状数组+离散化来统计,树状数组下标是维护的是排序序号,维护小于该序号的数字的区间总数前缀和,但是要注意要加上本身的区间,因为我们统计的只是小于,本身要+1,如果没有小于他的数,他的序号也是1,还是要+1,这里利用树状数组在时间上的插入保证了统计的一定是在a[i]前面的数 树状数组和线段树的这个性质常考

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#include<map>
#define ll long long
 
using namespace std;
const ll mod=1e9+7;
const int maxn=5e5+10;
map<int,int>mp;
ll c[maxn],sum[maxn];
int n,a[maxn],b[maxn];
void add(int x,int y)
{
   for(;x<=n;x+=x&-x)c[x]+=y; 
}
ll ask(int x)
{
   ll ans=0;
   for(;x;x-=x&-x)ans+=c[x];
   return ans;
}
int main()
{ 
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
       scanf("%d",&a[i]);
       b[i]=a[i]; 
    }
    sort(b+1,b+1+n);//离散化
    for(int i=1;i<=n;++i)
        mp[b[i]]=i;
    for(int i=1;i<=n;++i)
    {
       sum[i]=ask(mp[a[i]])*(n-i+1)%mod;    //前面比他小的
       add(mp[a[i]],i);     //左边区间个数 
    }
    for(int i=1;i<=n;++i)
        c[i]=0;
    for(int i=n;i>=1;--i)
    {
       sum[i]=(sum[i]+ask(mp[a[i]])*i%mod)%mod;   //右边比他小
       add(mp[a[i]],n-i+1);
       sum[i]=(sum[i]+(ll)(n-i+1)*i%mod)%mod;//还要统计自己d的
    }
    ll ans=0;
    for(int i=1;i<=n;++i)
        ans=(ans+(ll)a[i]*sum[i]%mod)%mod;
    printf("%lld\n",ans);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的纺织品企业财务管理系统,源码+数据库+毕业论文+视频演示 在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对纺织品企业财务信息管理的提升,也为了对纺织品企业财务信息进行更好的维护,纺织品企业财务管理系统的出现就变得水到渠成不可缺少。通过对纺织品企业财务管理系统的开发,不仅仅可以学以致用,让学到的知识变成成果出现,也强化了知识记忆,扩大了知识储备,是提升自我的一种很好的方法。通过具体的开发,对整个软件开发的过程熟练掌握,不论是前期的设计,还是后续的编码测试,都有了很深刻的认知。 纺织品企业财务管理系统通过MySQL数据库与Spring Boot框架进行开发,纺织品企业财务管理系统能够实现对财务人员,员工,收费信息,支出信息,薪资信息,留言信息,报销信息等信息的管理。 通过纺织品企业财务管理系统对相关信息的处理,让信息处理变的更加的系统,更加的规范,这是一个必然的结果。已经处理好的信息,不管是用来查找,还是分析,在效率上都会成倍的提高,让计算机变得更加符合生产需要,变成人们不可缺少的一种信息处理工具,实现了绿色办公,节省社会资源,为环境保护也做了力所能及的贡献。 关键字:纺织品企业财务管理系统,薪资信息,报销信息;SpringBoot
"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法和数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值