Dwango Programming Contest V 翻车记
Posted gloid
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dwango Programming Contest V 翻车记相关的知识,希望对你有一定的参考价值。
A:签到。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 110 char getc(){char c=getchar();while ((c<‘A‘||c>‘Z‘)&&(c<‘a‘||c>‘z‘)&&(c<‘0‘||c>‘9‘)) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,a[N],s,ans=0; int calc(int k){return abs(s-a[k]*n);} int main() { /*#ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); const char LL[]="%I64d "; #else const char LL[]="%lld "; #endif*/ n=read(); for (int i=1;i<=n;i++) s+=a[i]=read(); for (int i=2;i<=n;i++) if (calc(i)<calc(ans+1)) ans=i-1; cout<<ans; return 0; }
B:按位从高到低贪心,对当前位数一下有多少个子区间和该位为1,如果能满足要求就将其统计入答案并删掉所有该位为0的子区间和。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 1010 char getc(){char c=getchar();while ((c<‘A‘||c>‘Z‘)&&(c<‘a‘||c>‘z‘)&&(c<‘0‘||c>‘9‘)) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,m,b[N],cnt=0; ll a[N*N],c[N*N],ans; int main() { /*#ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); const char LL[]="%I64d "; #else const char LL[]="%lld "; #endif*/ n=read(),m=read(); for (int i=1;i<=n;i++) b[i]=read(); for (int i=1;i<=n;i++) { a[++cnt]=b[i]; for (int j=i+1;j<=n;j++) cnt++,a[cnt]=a[cnt-1]+b[j]; } n=cnt; for (int j=40;~j;j--) { int s=0; for (int i=1;i<=n;i++) if (a[i]&(1ll<<j)) c[++s]=a[i]; if (s>=m) { ans+=1ll<<j;n=s; for (int i=1;i<=s;i++) a[i]=c[i]; } } cout<<ans; return 0; }
C:指针从左到右扫一遍,两个队列分别维护指针左方D的出现位置和右方C的出现位置,并记录跨过当前位置的合法D~C区间有多少个。如果指针扫到M就更新答案,扫到D将其加入左边队列并统计以该位置为左端点的合法D~C区间数量,扫到C将其弹出右边队列并统计以该位置为右端点的合法D~C区间数量,拿两个指针记录两个队列中能产生贡献的边界位置即可做到线性。为啥atcoder不define ONLINE_JUDGE啊白交了一发。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 1000010 char getc(){char c=getchar();while ((c<‘A‘||c>‘Z‘)&&(c<‘a‘||c>‘z‘)&&(c<‘0‘||c>‘9‘)) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,q,m,a[N],b[N],c[N]; char s[N]; int main() { n=read();scanf("%s",s+1); for (int i=1;i<=n;i++) if (s[i]==‘D‘) a[i]=0; else if (s[i]==‘M‘) a[i]=1; else if (s[i]==‘C‘) a[i]=2; else a[i]=-1; q=read(); while (q--) { m=read(); int hb=1,tb=0,hc=1,t=0,tc=0;ll ans=0,cur=0; for (int i=1;i<=n;i++) if (a[i]==2) b[++tb]=i; for (int i=1;i<=n;i++) if (a[i]==1) ans+=cur; else if (a[i]==0) { c[++tc]=i; while (t<tb&&b[t+1]-i+1<=m) t++; cur+=t-hb+1; } else if (a[i]==2) { while (hc<=tc&&i-c[hc]+1>m) hc++; cur-=tc-hc+1; hb++; } cout<<ans<<endl; } return 0; }
D:好像还不太会啊。
E:没看。
感觉atcoder赛制不是非常友好啊。result:rank 185 rating +352
以上是关于Dwango Programming Contest V 翻车记的主要内容,如果未能解决你的问题,请参考以下文章
Dwango Programming Contest 6th C
Dwango Programming Contest 6th Task C. Cookie Distribution