思路:前缀和,但是忘了特判全是1的情况
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 100100 using namespace std; int len,num,ans=0x7f7f7f7f; char s[MAXN]; int sum[MAXN]; int main(){ freopen("reverse.in","r",stdin); freopen("reverse.out","w",stdout); scanf("%s",s); len=strlen(s); sum[0]=s[0]-'0'; if(s[0]=='1') num++; for(int i=1;i<len;i++){ sum[i]=sum[i-1]+s[i]-'0'; if(s[i]=='1') num++; } if(num==len){ cout<<"0"; return 0; } for(int i=0;i<len;i++) ans=min(ans,sum[i]+(len-1-i-sum[len-1]+sum[i])); cout<<ans; }
思路:哈希+组合数学。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n; long long ans,maxn=0; int vis[10],cnt[10000000]; int p[11]={41,47,53,59,61,97,71,73,83,89}; int main(){ freopen("number.in","r",stdin); freopen("number.out","w",stdout); scanf("%d",&n); for(int x,t,i=1;i<=n;i++){ long long tmp=0; for(x=i;x;x/=10){ t=x%10; if(!vis[t]) tmp+=(t+233)*p[t]; vis[t]=1; } maxn=max(maxn,tmp); memset(vis,0,sizeof(vis)); cnt[tmp]++; } for(int i=9553;i<=maxn;i++) if(cnt[i]) ans+=cnt[i]*(cnt[i]-1)/2; cout<<ans; }
正解思路:
枚举,用vis一个二进制数组表示当前数每一位的状态,出现或者不出现。
然后把二进制转为十进制,cnt[十进制]+1。
最后因为要求多少对,所以答案累加C(i,2)。
#include<cstdio> #define maxn 2000 using namespace std; int n,v[maxn]; long long ans; int main(){ freopen("number.in","r",stdin); freopen("number.out","w",stdout); int a,b,x; scanf("%d",&n); for(int i=1;i<=n;i++){ a=i;x=0; while(a){ b=a%10; x|=1<<b; a=a/10; } ans+=v[x]; v[x]++; } printf("%I64d ",ans); }
思路:贪心,在满足k的限制下,偶数项尽量大,奇数项尽量小。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 2000007 using namespace std; int a[MAXN]; int n,k,m,ans,cur; int main(){ scanf("%d%d",&n,&k); for(int i=0;i<n;i++) scanf("%d",&a[i]); ans=1;m=0;cur=a[0]; for(int i=1;i<n;i++){ if(m) if(cur-a[i]>=k) m=0,ans++,cur=a[i]; else cur=max(cur,a[i]); else if(a[i]-cur>=k) m=1,ans++,cur=a[i]; else cur=min(cur,a[i]); } printf("%d ",ans); return 0; }