Logo wuziyue的博客

博客

2023年4月月赛3 题解

2023-04-23 20:48:59 By wuziyue

Q1

简单题

k<=50,可以直接穷举

主代码:

    if(n%10==0){
            n/=10;
        }
        else n--;

Q2

首先 每个数字最终要%m

所以:答案<m

做法:

1.a序列全部%m(无需解释)

2.a,b,sort排序

关键点: 将a数组同加一个数并%M,使其等于B数组

如:a=1,1,2,2,2,3,3
    b=2,2,3,3,3,4,4
  how?
  1.找到b中最小数的个数(如:2,2个)
  2.在a中找对应个数(如:1,4,都是2个)
  3.一一测试正确性并打擂最小值

上代码:

    #include<bits/stdc++.h>
using namespace std;
int a[2005],b[2005];
int n,m;
bool check(int l){
    int tmp[2005];
    for(int i=1;i<=n;i++){
        tmp[i]=a[i]+l;
        tmp[i]%=m;
    }
    sort(tmp+1,tmp+n+1);
    for(int i=1;i<=n;i++){
        if(tmp[i]!=b[i]){
            return 0;
        }
    }
    return 1;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        a[i]%=m;
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&b[i]);
    }
    sort(b+1,b+n+1);
    sort(a+1,a+n+1);
    int sum=1;
    while(b[sum+1]==b[sum]) sum++;
    int q=n,ans=1000000005;
    if(check(0)){
        printf("%d",0); 
        return 0;
    }
    a[0]=-10000;
    for(int i=n-1;i>=0;i--){
        if(a[i]!=a[i+1]){
            if(q-i==sum){
                if(check((m+b[1]-a[i+1])%m)){
                    ans=min(ans,(m+b[1]-a[i+1])%m);
                }    
            }
            q=i;
        }
    }
    printf("%d",ans);
    return 0;
}

Q3 若两个学校与A联通且不经过点B,则这两个学校无需同时经过点B

同理:若两个学校与B联通且不经过点A,则这两个学校无需同时经过点A

此时,剩下的学校组合即为必须同时经过A,B

废话不多说:

         #include<bits/stdc++.h>
using namespace std;
long long int d[2],sum;
vector<int> aa[100005],aa2[100005];
bool f[100005];
void sss(int l){
    sum++;
    f[l]=1;
    for(int i=0;i<aa[l].size();i++){
        if(!f[aa[l][i]]) sss(aa[l][i]);
    }
}
void sss2(int l){
    sum++;
    f[l]=1;
    for(int i=0;i<aa2[l].size();i++){
        if(!f[aa2[l][i]]) sss(aa2[l][i]);
    }
}
int main(){
    int n,m,a,b,x,y;
    scanf("%d%d%d%d",&n,&m,&a,&b);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        if(x!=a&&y!=a){
            aa[x].push_back(y);
            aa[y].push_back(x);
        }
        if(x!=b&&y!=b){
            aa2[x].push_back(y);
            aa2[y].push_back(x);
        }
    }
    f[a]=1;
    sum=0;
    sss(b);
    d[0]=n-sum-1;
    memset(f,0,sizeof(f));
    f[b]=1;
    sum=0;
    sss2(a);
    d[1]=n-sum-1;
    printf("%lld",d[0]*d[1]);
    return 0;
}

评论

徐子昂
谢谢请教@wuziyue
tingting
thank you @wuziyue
liyuan2012
@wuziyue Thanks.
lhx2022
oo00-

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。