競賽題解 - CF Round #524 Div.2
CF Round #524 Div.2 - 競賽題解
不容易CF有一場下午的比賽,開心的和一個神犇一起報了名
被虐爆……前兩題水過去,第三題卡了好久,第四題毫無頭緒QwQ
Codeforces 傳送門
Tab, 先寫了ABC題,後面的之後再補 QwQ
『解析』
A-Petya and Origami
讀懂題意就會做……根據題意可以求出3種"sheet"各自需要的數量,然後每一種的數量除以k向上取整後求和就是答案。
B-Margarite and the best present
簡單的數學題,根據題意可以將數列分成兩部分:
\[-1,-3,-5,-7,... (奇數且負數)\\ 2,4,6,8,... (偶數且正數) \]
hh……兩個等差數列。稍微注意一下左右兩端點的值然後等差數列求和就可以了
C-Masha and two friends
沒看懂官方給的那個演算法標籤是什麼……
(@[email protected]) 不管,反正我覺得我的演算法沒問題……(其實主要想講這道題)
首先進行的操作是將閉區間變成左開右閉區間和上開下閉區間,這樣的效果就是這樣:
原來的左下角為\((0,0)\),右上角為\((5,3)\)的矩形是這樣:
進行操作過後就長這樣:
可以看出來兩種矩形覆蓋到的方格的個數是一樣的……
這步操作主要是為了方便判斷重疊。
然後把矩形存成了一個儲存了上下左右邊界(u,d,l,r)的結構體,然後根據它的左下角座標和長寬就可以算出它裡面的黑白格子分別有多少個。
for example……
比如左下角為\((0,0)\),右上角為\((4,4)\)的矩形,
因為左下角的格子是白色的,所以這個矩形裡白色一定不比黑色少(比較簡單)
又因為它的長寬是3,3(這裡看格子的個數),所以面積為9,較多的格子有5個,另一種格子有4個。
所以白色有5個,黑色有4個。
接下來就套用漂浮法:先在第一層放上黑色的矩形(下面稱矩形A)(因為題目中它是最後一個放上去的矩形),然後嘗試漂浮白色的矩形(下面稱矩形B)——如果與矩形A沒有重疊,則全部漂浮上去;否則如果矩形B的左邊與矩形A重疊,就把矩形B按矩形A的左邊界分為左右兩半,etc.
再舉個例子:
如果矩形B的右邊與矩形A相交,那麼分割就會像這樣:
OK~切下來的矩形都會“漂浮”上去,對這些矩形統計塗色後各顏色塊的變化數量就可以了~
『原始碼』
A-Petya and Origami
/*Lucky_Glass*/
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,k;
scanf("%d%d",&n,&k);
double A=n*2,B=n*5,C=n*8;
printf("%lld\n",(long long)ceil(A/k)+(long long)ceil(B/k)+(long long)ceil(C/k));
return 0;
}
B-Margarite and the best present
/*Lucky_Glass*/
#include<bits/stdc++.h>
using namespace std;
int main(){
int T;scanf("%d",&T);
while(T--){
long long l,r;
scanf("%lld%lld",&l,&r);
long long fl,fr,gl,gr;
if(l%2) fl=l,gl=l+1;
else gl=l,fl=l+1;
if(r%2) fr=r,gr=r-1;
else gr=r,fr=r-1;
long long ans=0;
if(gl<=gr) ans+=(gl+gr)*((gr-gl)/2+1)/2;
if(fl<=fr) ans-=(fl+fr)*((fr-fl)/2+1)/2;
printf("%lld\n",ans);
}
return 0;
}
C-Masha and two friends
/*Lucky_Glass*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5;
struct SQUARE {
int l,r,u,d,col;
pair<ll,ll> GetArea() {
ll R=u-d,C=r-l,A,B;
if(C%2) {
if(R%2) A=R/2*C+C/2+1,B=R/2*C+C/2;
else A=R/2*C,B=R/2*C;
} else {
if(R%2) A=R/2*C+C/2,B=R/2*C+C/2;
else A=R/2*C,B=R/2*C;
}
if(d%2==l%2) return make_pair(A,B);
else return make_pair(B,A);
}
} squ[N+5];
int n;
ll wht,blk;
void Floatage(int dep,SQUARE now) {
if(now.l>=now.r || now.d>=now.u) return;
while(dep<=n && (now.l>=squ[dep].r || now.r<=squ[dep].l || now.u<=squ[dep].d || now.d>=squ[dep].u))
dep++;
if(dep>n) {
pair<ll,ll> _now=now.GetArea();
if(now.col) wht-=_now.first,blk+=_now.first;
else wht+=_now.second,blk-=_now.second;
return;
}
SQUARE las=squ[dep],nxt;
if(now.l<las.l) {
nxt=now;
nxt.r=las.l;
Floatage(dep+1,nxt);
now.l=las.l;
}
if(now.r>las.r) {
nxt=now;
nxt.l=las.r;
Floatage(dep+1,nxt);
now.r=las.r;
}
if(now.u>las.u) {
nxt=now;
nxt.d=las.u;
Floatage(dep+1,nxt);
now.u=las.u;
}
if(now.d<las.d) {
nxt=now;
nxt.u=las.d;
Floatage(dep+1,nxt);
now.d=las.d;
}
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
SQUARE bak;
bak.l=bak.d=1;
n=2;
scanf("%d%d",&bak.u,&bak.r);
bak.u++;bak.r++;
pair<ll,ll> _bak=bak.GetArea();
wht=_bak.first,blk=_bak.second;
for(int i=0; i<2; i++) //left,down,right,up
scanf("%d%d%d%d",&squ[i].l,&squ[i].d,&squ[i].r,&squ[i].u),squ[i].col=i,
squ[i].r++,squ[i].u++;
for(int i=1; i>=0; i--)
Floatage(i+1,squ[i]);
printf("%lld %lld\n",wht,blk);
}
return 0;
}
\(\mathcal{THE\ END}\)
\(\mathfrak{Thanks\ for\ reading!}\)
有什麼沒看懂的可以在 \(lucky\[email protected]\) 裡問(經常看郵箱一族)