AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html
$AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$题解
本次$ARC$可谓是手速场。当时由于博主实在zz导致滚粗,rk89.
下面是题解。
总结了一下,三道结论题。样例都不错,猜到结论基本上就可以过掉了。
严重差评!!!大概要涨不了多少rating了QAQ(暴露了我的Rating是多么低),xza怎么没来??
(UPD:2018-04-07 21:53):果然没上黄好难受还差12分QAQ。
$C$
题意
有三个整数$A,B,C$。每次可以选择一个数让他加$2$,或者选择任意两个数让他们同时加$1$,问最少几次使$3$个数相同。
题解
傻逼结论题。
假设$A\geq B\geq C$,那么最优策略下,最终的数字大小不会超过$A+1$。
考虑填掉$B$和$C$的坑,每次填坑效率为$2$,如果坑的总体积为奇数,那么自然要整体再加一层(包括$A$)坑的深度也$+1$。偶数直接填完就可以了。
由于这个结论太傻逼了,我表示不会证。
上面的那些全部瞎逼逼,正确的证明大概是:由题意的,本题显然可以这样做QAQ。
代码
#include <cstring> #include <cstdio> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; int A,B,C; int main(){ scanf("%d%d%d",&A,&B,&C); if (A<B) swap(A,B); if (A<C) swap(A,C); int ans=A-B+A-C; if (ans%2) ans+=3; ans/=2; printf("%d",ans); return 0; }
$D$
题意
在$2$次$10^{10^{10}}$人的比赛中,你取得的成绩依次为第$a$名和第$b$名。
当一个人的成绩为$A$和$B$时,当且仅当$AB<ab$时,他会在综合排名中排在你前面。
显然同一次比赛的同一个名次只能被一个人拥有。
现在问综合排名排在你前面的最多有多少人?
题解
有趣的结论题。
设$c=ab-1$,考虑到答案中的所有的$A$和$B$,都满足$AB\leq c$。
设$d=\left\lfloor \sqrt c \right\rfloor$,则对于$A\in[1,d]$都会有唯一且不重复的$B\in[d,c]$来接应,同理,对于$B\in[1,d]$都会有唯一且不重复的$A\in[d,c]$来接应。
然后我们考虑删减掉一些不能用的。
第一,是前后两种情况重叠的,就是会出现$A=B=d$的情况,但是算了两次的,要减一。$if (\left\lfloor\frac cd\right\rfloor=d) \rightarrow\ ans=ans-1$
第二,就是要删掉被你占用的在$[1,d]$的排名。
所以代码也很短咯。
代码
#include <cstring> #include <cstdio> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; typedef long long LL; int Q; LL a,b; LL LLsqrt(LL x){ LL L=0,R=1e9,mid,ans=-1; while (L<=R){ mid=(L+R)>>1; if (mid*mid<=x) L=mid+1,ans=mid; else R=mid-1; } return ans; } int main(){ scanf("%d",&Q); while (Q--){ scanf("%lld%lld",&a,&b); if (a>b) swap(a,b); LL c=a*b-1; LL d=LLsqrt(c); LL ans=d+d; if (a!=b) ans--; if (d!=0) if (d==c/d) ans--; printf("%lld\n",max(ans,0LL)); } return 0; }
$E$
题意
给出长度为$n$的序列$A$、$B$,序列$A$的第$i$项为$A_i$,序列$B$的第$i$项为$B_i$,且$\sum_{i=1}^{n}A_i=\sum_{i=1}^{n}B_i$。
现在$Tozan$和$Gezan$在进行下面的一系列操作:
- 如果$A$与$B$相同了,停止操作。
- $Tozan$让$A$中任意一个正元素减一。
- $Gezan$让$B$中任意一个正元素减一。
- 给你一个糖。
事实上,$Tozan$想给你尽可能多的糖,而$Gezan$恰恰相反,问双方都执行最优策略的情况下,你能得到多少糖。
题解
又是一道结论题。
首先判掉答案为0的。
然后答案显然是$min\{B_i\}\ \ \ (1\leq i\leq n$且$A_i>B_i)$
为什么呢。
显然啊
额
好吧我说。
我们只需要分两块证明。
一个是$Tozan$有办法操作这么多次。
另一个是$Gezan$有办法不让$Tozan$再继续操作。
第二个很好证啊,那我只说说第一个。
假设第$i$个是你选出的不拿光的那个。
你只要考虑除了你留下的那一个,其他的所有的总的效果是$Tozan$剩下的比$Gezan$剩下的少,那么$Gezan$要努力停止操作必然要让其他剩余的总和变得相等。于是$Tozan$就可以把剩下的都弄光。对于当前的,当$Tozan$弄到$A_i=B_i$的时候,$Gezan$必定刚好可以把其他的都弄完,所以这时会停止操作。显然$Gezan$不会中途去弄$B_i$,因为这样显然亏。
感觉这个还是要感性理解。
我感觉舌头要打结了。QAQ
估计我写的中文没有可读性QAQ。
代码
#include <cstring> #include <cstdio> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; typedef long long LL; const int N=200005; int n; struct Node{ int a,b; }x[N]; bool pd(){ for (int i=1;i<=n;i++) if (x[i].a!=x[i].b) return 0; return 1; } int main(){ LL tot=0; scanf("%d",&n); for (int i=1;i<=n;i++){ scanf("%d%d",&x[i].a,&x[i].b); tot+=x[i].a; } if (pd()){ printf("0"); return 0; } int ans=2e9; for (int i=1;i<=n;i++) if (x[i].a>x[i].b) ans=min(ans,x[i].b); printf("%lld",tot-ans); return 0; }
$F$
暂时不会啊(挖坑待填)