湖南模拟套题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; }
我先枚举的每个数,然后求出他们的出现的数,然后对于每一个数将他的存在的[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; }
#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; }
/* 枚举,用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; }
这个题的正解竟然是一个叫贪心的神奇的算法。
我们在满足相邻的数的差值>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; }
以上是关于湖南模拟套题2的主要内容,如果未能解决你的问题,请参考以下文章