Codeforces Round #133 (Div. 2)
A.
六角形の個数を求めます。
2<=a,b,c
であるから、a=b=c=2のときを考えて、a,b,cが増えるときどの程度増えるかを考えれば解けます。
int main(){ int a,b,c,ans=7; cin>>a>>b>>c; a-=2;b-=2;c-=2; ans+=a*3; ans+=b*(a+3); ans+=c*(a+b+3); cout<<ans<<endl; return 0; }
B.
解けない。
C.
貪欲法で解けます。
1日ずつ進めて行って、その日の人数が足りなければ、追加して、次の日に誰もいなければ1人追加しておきます。
この解法で、1日目から、n+m-1日目まで調べれば、n+m日目も鍵を渡せて、それ以降も条件を満たします。
int d[5000],w[5000]; int main(){ int n,m,k; cin>>n>>m>>k; int pos = 0; while(pos<n+m){ if(w[pos]<k){ int t=k-w[pos]; d[pos]+=t; for(int i = 0; i < n; i++){ w[pos+i]+=t; } } if(w[pos+1]==0){ d[pos]++; for(int i = 0; i < n; i++){ w[pos+i]+=1; } } pos++; } int ans=0; for(int i = 0; i <=m+n; i++)ans+=d[i]; cout<<ans<<endl; int f=0; for(int i = 0; i <=m+n; i++){ while(d[i]--){ if(f)cout<<' '; cout<<i+1; f=1; } } return 0; }
D.
未読
E.
n進法でabcd([abcd]nとする)があったとき、1桁の数字ができるまで、各桁の和を計算するとき、その1桁の数字は(a+b+c+d)%(n-1)になります(ただし、0になって、a+b+c+d!=0のときはn-1になります)。1が1になることと、n-1になる数字に1を足すと1になる数字になることなどから、分かります。
a_0(=0とする)からa_m(0<=m<=n)までの和(をk-1で割った余り)をすべて計算しておきます。
s_m=a_0+a_1+...+a_mとすると、
a_i+a_(i+1)+...+a_j = s_j - s_(i-1)となるので、a_iからa_jまでの和をO(1)で求められるようになります。
あとは、mapを使って、(s_i+b)%(k-1)=s_j (i
typedef long long ll; map<int,int> d; int s[100001]; int main(){ int k,b,n; ll ans0=0,ans=0; cin>>k>>b>>n; k--; ll zero=0; ++d[0]; for(int i = 0; i < n; i++){ int a; scanf("%d",&a); s[i+1]=(s[i]+a)%k; ++d[s[i+1]]; if(a==0)zero++; else{ ans0+=zero*(zero+1)/2; zero=0; } } ans0+=zero*(zero+1)/2; if(b==0){ cout<<ans0<<endl; return 0; } if(b%k==0){ for(int i = 0; i <= n; i++){ ll t=d[s[i]]; ans+=t*(t-1)/2; d[s[i]]=0; } cout<<ans-ans0<<endl; return 0; } d.clear(); for(int i = n; i >= 0; i--){ int x=(s[i]+b)%k; ans+=d[x]; d[s[i]]++; } cout<<ans<<endl; return 0; }