湖南模拟套题2

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了湖南模拟套题2相关的知识,希望对你有一定的参考价值。

技术分享

难度:☆☆

 

 

技术分享

 

没有考虑当s1>s2的这种情况,在这个时候ans应该为0,但是如果不在赋一下值的话,ans=N

我们可以用一个sum数组分别记录一下1的前缀和与0的前缀和,然后我们再找出第一个出现1的位置s1和最后一个出现0的位置s2,当s2<s1的时候,说明0全都在1的前面,最终答案即为0,当s2>s1的时候,我们可以知道一定是在s1~s2这段区间内出现了问题,我们要修改的值也一定都是这个区间内的。接下来我们可以枚举最后一个0的位置,然后修改的数的个数即为这个位置往前的1的个数+这个位置往后的0的个数,然后更新最小值,在枚举最后一个0的位置的时候我们可以直接把这个位置从s1-1开始枚举

技术分享
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 100002
using namespace std;
char ch[N];
int s,s1,s2,ans,sum[2][N];
int read()
{
    int x=0,f=1; char 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 0;
}
int main()
{
    freopen("reverse.in","r",stdin);
    freopen("reverse.out","w",stdout);
    cin>>ch;ans=s1=N;
    int l=strlen(ch);
    for(int i=0;i<l;i++)  
    {
        if(ch[i]==0) sum[0][i]=sum[0][i-1]+1,sum[1][i]=sum[1][i-1];
        else s1=min(s1,i),sum[1][i]=sum[1][i-1]+1,sum[0][i]=sum[0][i-1];
    }
    for(int i=l-1;i>0;i--) if(ch[i]==0) {s2=i; break;}
    for(int i=s1-1;i<=s2;i++)
    {
        s=sum[1][i]-sum[1][s1-1]+sum[0][s2]-sum[0][i];
        if(ans>s) ans=s;
    } 
    if(s1>s2) ans=0;
    printf("%d",ans);
    return 0;
}
AC代码

 

 

技术分享

 

我先枚举的每个数,然后求出他们的出现的数,然后对于每一个数将他的存在的[0,9]内的数转化成一个整数,然后求出每个整数出现的次数,再用一下组合数乱搞一下就好了,然后就光荣的TLE了

技术分享
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 10000010
#define LL long long
using namespace std;
bool vist[10];
int n,l,w,s,a[10],sum,q[N],num[N];
long long ans;
int read()
{
    int x=0,f=1; char 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 work()
{
    for(int i=1;i<=n;i++)
    {
        s=i,w=0;
        memset(vist,0,sizeof(vist));
        while(s)
        {
            if(vist[s%10]) {s/=10;continue; }
            vist[s%10]=true;
            a[++w]=s%10;
            s/=10;
        }
        sort(a+1,a+1+w);s=0;
        for(int i=1;i<=w;i++)
         s=s*10+a[i];
        if(a[1]==0) s*=10;
        q[++sum]=s;
    }
    sort(q+1,q+1+sum);s=0;
    for(int i=1;i<=sum;i++)
     if(q[i]!=q[i-1]) num[++s]++;
     else num[s]++;
    for(int i=1;i<=s;i++)
     if(num[i]>=2)
      ans+=(LL)(num[i]-1)*num[i]/2;
    printf("%I64d",ans);
}
int main()
{
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    n=read();s=n;
    work();
    return 0;
}
30分TLE代码
技术分享
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 10000010
#define LL long long
using namespace std;
bool vis[10];
int n,l,w,s,a[10],sum,q[N],num[N],maxn;
long long ans;
int read()
{
    int x=0,f=1; char 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 work()
{
    for(int i=1;i<=n;i++)
    {
        s=i,w=0;
        while(s){vis[s%10]=true;s/=10;}
        for(int j=1;j<=9;j++)
         if(vis[j]) s=s*10+j,vis[j]=0;
        if(vis[0]) s*=10,vis[0]=0;
        if(maxn<s) maxn=s;
        q[s]++;
    }
    for(int i=1;i<=maxn;i++)
      ans+=(LL)(q[i]-1)*q[i]/2;
    printf("%I64d",ans);
}
int main()
{
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    n=read();
    work();
    return 0;
}
在本机上跑第14个点超时
技术分享
/*
枚举,用vis一个二进制数组表示当前数每一位的状态,出现或者不出现。 
然后把二进制转为十进制,cnt[十进制]+1。
最后因为要求多少对,所以答案累加C(i,2)。 
*/
#include<iostream>
#include<cstdio>
#include<cstring>

#define size 1024

using namespace std;
int n,cnt[size],vis[10];
int Use[10]={1,2,4,8,16,32,64,128,256,512};
long long ans;

int main()
{
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    cin>>n;
    int start,End;
    for(int i=1;i<=n;i++)
    {
        start=i;End=0;memset(vis,0,sizeof vis);
        while(start) vis[start%10]=1,start/=10;
        for(int j=0;j<=9;j++) if(vis[j]) End+=Use[j];
        cnt[End]++;
    }
    for(int i=0;i<size;i++) ans+=1ll*cnt[i]*(cnt[i]-1)/2;
    cout<<ans<<endl;
    fclose(stdin);fclose(stdout);
    return 0;
}
标程

 

 

技术分享

 

技术分享
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 2000010
using namespace std;
int n,k,sum,mid,ans,a[N],b[N];
int read()
{
    int x=0,f=1; char 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;
}
void dfs(int now,int s)
{
    if(now==n+1) {ans=max(ans,s);return;}
    if(s%2==0&&b[s]) if(b[s]<b[s-1]) return ;
    if(s%2!=0&&b[s]&&s>1) if(b[s]>b[s-1]) return ;
    if(abs(b[s]-b[s-1])<k&&s>1) return ;
    for(int i=now;i<=n;i++)
    {
        b[s+1]=a[i],dfs(i+1,s+1),b[s+1]=0;
        dfs(i+1,s);
    } 
}
int main()
{
    freopen("wave.in","r",stdin);
    freopen("wave.out","w",stdout);
    n=read(),k=read();
    for(int i=1;i<=n;i++) a[i]=read();
    dfs(1,0);
    printf("%d",ans);
    return 0;
}
SB搜索,就搜了5分

这个题的正解竟然是一个叫贪心的神奇的算法。

我们在满足相邻的数的差值>k的情况下,使奇数位上的数尽量小,偶数位上的数尽量大

技术分享
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 2000010
using namespace std;
int n,k,q,m,ans,a[N];
int read()
{
    int x=0,f=1; char 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 main()
{
    freopen("wave.in","r",stdin);
    freopen("wave.out","w",stdout);
    n=read(),k=read();
    for(int i=1;i<=n;i++) a[i]=read();
    ans=1;q=a[1],m=1;
    for(int i=2;i<=n;i++)
    {
        if(m)
         if(a[i]-q>=k) 
          m=0,ans++,q=a[i];
         else q=min(q,a[i]);
        else
         if(q-a[i]>=k)
          m=1,ans++,q=a[i];
         else q=max(q,a[i]);
    }
    printf("%d",ans);
    return 0;
}
AC代码

 

 

以上是关于湖南模拟套题2的主要内容,如果未能解决你的问题,请参考以下文章

2019湖南多校第四场

ACM--模拟--nyoj 559--报数游戏--湖南第七届省赛

湖南青马刷视频刷题软件分享

每天一套题打卡|河南省第九届ACM/ICPC

NOI模拟赛(湖南)DeepDarkFantasy

2019合工大共创五套卷(数一数二数三)模拟卷一+答案PDF