Wannafly模拟赛3

来源:互联网 发布:cs1.6中文版for mac 编辑:程序博客网 时间:2024/06/10 05:02

题目链接:https://www.nowcoder.com/acm/contest/13#question

A.反蝴蝶效应

#include<cstdio>#include<algorithm>#include<iostream>using namespace std;const int maxn=100005;int n;int a[maxn];int main(){    cin>>n;    int ans=0; for(int i=1;i<=n;i++){     scanf("%d",&a[i]);       ans=max(a[i]+i-1,ans);      }    cout<<ans<<endl;}


B.贝伦卡斯泰露

dfs暴力搜索,加几个优化

1.首先判断相同的数是否出现偶数次

2.记录每个数的总出现次数,若在某一个集合出现偶数次则跳出

3.若对于两个集合已经选择的数已经不是对应相等则跳出

#include<cstdio>#include<algorithm>#include<iostream>#include<vector>#include<cstring>using namespace std;vector<int> g1;vector<int> g2;int read(){    char ch;    int x=0,f=1;ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int a[45],num[45],num1[45],num2[45];int n;bool dfs(int x){    int z=min(g1.size(),g2.size());    if(x==n+1){        if(z!=n/2)            return false;        for(int i=0;i<n/2;i++){            if(g1[i]!=g2[i])                return false;        }        return true;    }    if(g1.size()>n/2||g2.size()>n/2)        return false;     for(int i=0;i<z;i++){        if(g1[i]!=g2[i])            return false;    }    int p=a[x];    if(num1[p]<num[p]/2){        num1[p]++;        g1.push_back(p);        if(dfs(x+1))            return true;        num1[p]--;        g1.pop_back();    }    if(num2[p]<num[p]/2){        num2[p]++;        g2.push_back(p);        if(dfs(x+1))            return true;        num2[p]--;        g2.pop_back();    }    return false;}int main(){    int t;    scanf("%d",&t);    while(t--){        memset(num,0,sizeof(num));        memset(num1,0,sizeof(num2));        memset(num2,0,sizeof(num2));        g1.clear();        g2.clear();        scanf("%d",&n);        for(int i=1;i<=n;i++){            scanf("%d",&a[i]);            num[a[i]]++;        }        bool f=1;        for(int i=1;i<=40;i++)            if(num[a[i]]%2!=0){                printf("Furude Rika\n");                f=0;                break;            }        if(!f)            continue;        if(dfs(1))            printf("Frederica Bernkastel\n");        else printf("Furude Rika\n");     }}



D.生物课程

首先只能有n-1条边,其次判断每个点所连接的点数,注意点较少时的特判

#include<cstdio>#include<algorithm>#include<iostream>using namespace std;const int maxn=100005;int n,m;int num[maxn];int main(){    cin>>n>>m;    for(int i=1;i<=m;i++){        int x,y;        cin>>x>>y;        if(x!=y){            num[x]++;            num[y]++;        }    }    if(m!=n-1){        cout<<"NotValid"<<endl;        return 0;    }    if(n==2){        if(m==1&&num[1]==num[2]&&num[1]==1)        cout<<"I"<<endl;        return 0;    }          sort(num+1,num+1+n);        if(num[1]==num[2]&&num[1]==1&&num[3]==num[n]&&num[3]==2){            cout<<"I"<<endl;            return 0;        }         if(n>=5&&num[n]==4&&num[n-1]<num[n]&&num[1]==num[4]&&num[1]==1&&num[4]<num[5]){            cout<<"X"<<endl;            return 0;        }        if(n>=4&&num[n]==3&&num[n-1]<num[n]&&num[1]==num[3]&&num[1]==1&&num[3]<num[4]){            cout<<"Y"<<endl;            return 0;        }cout<<"NotValid"<<endl;}


E.绝对半径2051

首先将相同的数的下标记录到同一个vector里,再二分答案,对于每个容器里的数判断是否满足

#include<cstdio>#include<algorithm>#include<iostream>#include<vector>using namespace std;const int maxn=100005;  int z=0;struct P{int x,i;}p[maxn];int vis[maxn];int n,k;vector<int> g[maxn];int a[maxn];  int read(){    char ch;    int x=0,f=1;ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;} bool cmp(P a,P b){    if(a.x!=b.x)        return a.x<b.x;    return a.i<b.i;} bool C(int x){    for(int i=1;i<=z;i++)        for(int j=0;j<g[i].size();j++){            if(g[i].size()-j<x)                continue;            int c=j+x-1;            if(g[i][c]-g[i][j]+1>k+x)                continue;            return true;        }    return false;}int main(){     n=read();    k=read();    for(int i=1;i<=n;i++){        p[i].x=read();        a[i]=p[i].x;        p[i].i=i;    }    if(n==0){        printf("0\n");        return 0;    }    sort(p+1,p+1+n,cmp);     for(int i=1;i<=n;i++){        if(p[i].x!=p[i-1].x){            z++;            //vis[p[i].i]=z;        }        vis[p[i].i]=z;        g[z].push_back(p[i].i);       // cout<<z<<p[i].i<<vis[p[i].i]<<-1<<endl;    }//    for(int i=1;i<=z;i++){//        for(int j=0;j<g[i].size();j++)//            cout<<g[i][j]<<" ";//    cout<<-1<<endl;//    }    int l=1,r=1e9+1;    for(int i=1;i<=60;i++){        int mid=(l+r)/2;//cout<<mid<<endl;        if(C(mid))            l=mid;        else r=mid;    }    if(C(r))        printf("%d\n",r);    else printf("%d\n",l);}


F.监视任务

先将所有的区间按照右端点进行排序,根据贪心的思想,每次用树状数组求(l[i],r[i])区间的和,若大于等于k[i],则不需操作,否则从r[i]开始向左进行操作,将不是1的全部改为1,直至区间和为k[i]

#include<cstdio>#include<algorithm>#include<iostream>#include<vector>#include<cstring>using namespace std;const int maxm=1000005;const int maxn=500005;int bit[maxn],vis[maxn];int n,m;struct P{ int l,r,z;}p[maxm];int sum(int x){    int s=0;    while(x>0){        s+=bit[x];        x-=(x&-x);    }    return s;}void add(int x){    while(x<=n){        bit[x]+=1;        x+=(x&-x);    }}int read(){    char ch;    int x=0,f=1;ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}bool cmp(P a,P b){    if(a.r!=b.r)        return a.r<b.r;    return a.l<b.l;}int main(){    n=read();    m=read();    for(int i=1;i<=m;i++){        p[i].l=read();        p[i].r=read();        p[i].z=read();    }    sort(p+1,p+m+1,cmp);    for(int i=1;i<=m;i++){        int z=sum(p[i].r)-sum(p[i].l-1);         if(z>=p[i].z)            continue;   // cout<<z<<" "<<p[i].z<<-1<<endl;        int k=p[i].z-z;        for(int j=p[i].r;j>=p[i].l&&k>0;j--){            if(!vis[j]){                vis[j]=1;                k--;                add(j);            }        }    }    printf("%d\n",sum(n));}


原创粉丝点击