問題はこちら
No.178 美しいWhitespace (1) - yukicoder
s[i]:=a[i]+4*b[i]、M:=max(s[i])としたとき
∀i.M≡s[i] mod2 なら Σ(M-s[i])/2 を、さもなくば-1を出力する
Σの計算はintだとオーバーフローすることに注意
int main(){ long m=0,s=0; int a[1010],n,i,t; scanf("%d",&n); for(i=0;i<n;i++){ scanf("%d%d",a+i,&t); a[i]+=t*4; if(m<a[i])m=a[i]; } for(i=0;i<n;i++){ s+=m-a[i]; if(a[i]%2!=a[0]%2)break; } printf("%ld",i==n?s/2:-1); return 0; }
この方針で短くするとこうなる
long s,m; a[999],i,x; main(t){ for(gets(&t);~scanf("%d%d",&x,&t);m=x>m?x:m)a[i++]=x+=t*4; for(;i&~s%2;s+=m-a[--i]); i=!printf("%ld",s&1?-1:s/2); }
2つ目のfor文の終了条件i>0&&n%2==0を、n%2==0⇔~n%2==-1 を利用して短く書いている
ほかは特に工夫してない
でもよく考えると配列いらなくない?
long s,m; f,x,i; main(t){ for(gets(&t);~scanf("%d%d",&x,&t);){ x+=t*4; s+=m-x; //現時点までの最大値からの差を合計に足しておく f+=i++?m-x&1:0; //ダメフラグ if(m<x){s+=(x-m)*i;m=x;} //もし最大値が更新されているなら、今までの個数i×更新量(x-m)だけ合計を増やす } s=!printf("%ld",f?-1:s/2); }
m-xが何度も登場しているので、x+=t*4ではなくx+=4*t-mと置けばいくらか縮みそう
long s,m; f,x,i; main(t){ for(gets(&t);~scanf("%d%d",&x,&t);x>0?s+=x*i,m+=x:0)s-=x+=t*4-m,f+=i++>0&x; s=!printf("%ld",f?-1:s/2); }
125B
16/06/22追記
上ではフラグfには「0か非0」が入っていたので、これを「0か1」になるように f+=i++>0&x を f|=i++>0&x と書き換えれば
出力が -f|s/2 でできるようになる
long s,m; f,x,i; main(t){ for(gets(&t);~scanf("%d%d",&x,&t);x>0?s+=x*i,m+=x:0)s-=x+=t*4-m,f|=i++>0&x; s=!printf("%ld",-f|s/2); } 123B