CSP 2021 總結
PJ
開題順序:1342
應該先做 T2 ,導致我 T2 直接看錯
T1、T3
T1 :直接推規律即可,考場的想法應該正確
T3 :好家伙直接 map 走起
T2
最崩潰的來了 :\(5000\times8000=4e7\) 是吧,愣是給我看成了 \(4e8\)
然后想打插入排序(正解)騙分,發現插入排序不對,就直接 sort
。。。。。。。。
。。。。。。。。
。。。。。。。。
心 態 炸 裂
退役吧
T4
考試時想到雙鏈表,過了小數據,但沒過大數據
浪費了太多時間,導致了 T2 直接掛
總結
考試的心態不好,太急了,連 T1 都要好久才沉下心來想
今年的 pj 比較水,沒有說什么沒想到。
但是代碼實現弱 —— T4 掛了,並浪費大量時間
眼花繚亂——四千萬看成四億
TG
T1
直接枚舉廊橋+堆,暴力 \(O(nm\log n)\)
正解:設 \(c_i\) 表示 \(i\) 個廊橋能停靠的飛機,則 \(ans=\max c_{1,i}+c_{2,n-i}\)
考慮到每一個廊橋加入都會使得飛機可以停靠。
即 \(c_i=c_{i-1}+x\) , 因為 \(c_0=0\) ,於是可以通過已知 \(c_{i-1}\) 推出 \(c_i\)
考慮求 \(x\) ,因為先到先得,原有的廊橋是被占滿的,於是新加的廊橋只會影響沒有停廊橋的飛機
模擬,若當前飛機停靠的結束時間是 \(t\) ,每次查詢停靠開始時間最接近 \(t\) 的停靠,用一個 set 即可
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int n,m1,m2,c1[N],c2[N],ans;
struct rg {
int l,r;
bool operator <(rg A) const {
return l<A.l;
}
}x[N],y[N];
set<rg>S;
set<rg>::iterator it;
int main() {
freopen("airport.in","r",stdin);
freopen("airport.out","w",stdout);
scanf("%d%d%d",&n,&m1,&m2);
for(int i=1;i<=m1;i++)scanf("%d%d",&x[i].l,&x[i].r);
for(int i=1;i<=m2;i++)scanf("%d%d",&y[i].l,&y[i].r);
sort(x+1,x+m1+1);
sort(y+1,y+m2+1);
S.clear();
for(int i=1;i<=m1;i++)S.insert(x[i]);
for(int i=1,vl,p;i<=n;i++) {
vl=p=0;
while(1) {
it=S.lower_bound((rg){p,0});
if(it==S.end())break;
++vl,p=it->r,S.erase(it);
}
c1[i]=c1[i-1]+vl;
}
S.clear();
for(int i=1;i<=m2;i++)S.insert(y[i]);
for(int i=1,vl,p;i<=n;i++) {
vl=p=0;
while(1) {
it=S.lower_bound((rg){p,0});
if(it==S.end())break;
++vl,p=it->r,S.erase(it);
}
c2[i]=c2[i-1]+vl;
}
for(int i=0;i<=n;i++)
ans=max(ans,c1[i]+c2[n-i]);
printf("%d",ans);
}
T2
區間 dp ,想到后直接放棄
T3
大模擬,對於第一個是 \(L\) 或 \(R\) 分類討論
問題簡化為兩個棧,如何輪流彈出棧頂使序列是個回文序列
可通過奇怪證明,發現若能彈出則一定可以彈出。
於是按照字典序枚舉情況即可
考場就想到了正解,但是一些奇怪的錯誤被 hack 了
。。。。。。。。
。。。。。。。。
。。。。。。。。
心 態 炸 裂
退役吧
參考網絡題解:這里可以把棧變成雙端隊列,每次彈出一對相同的數,組成回文
#include<bits/stdc++.h>
using namespace std;
const int N=500005;
int T,n,x[N<<1],fl,p,ans[N<<1];
struct que {
int q[N<<1],l,r;
inline void clear() { l=1,r=0; }
inline void push(int a) { q[++r]=a; }
inline int Fr() { return q[l]; }
inline int Bk() { return q[r]; }
inline bool empty() { return l>r; }
inline void Pf() { ++l; }
inline void Pb() { --r; }
inline int Sz() { return r-l+1; }
}A,B;
void make(int op) {
int p1=1,p2=n;
if(op==1)++p1;
else --p2;
A.clear(),B.clear();
for(int i=p-1;i>=p1;i--)A.push(x[i]);
for(int i=p+1;i<=p2;i++)B.push(x[i]);
for(int i=2;i<=n/2;i++) {
if(A.empty() && B.empty())break;
if(B.empty()) {
if(A.Fr()!=A.Bk())
return;
ans[i]=ans[n-i+1]=1;
A.Pb(),A.Pf();
} else if(A.empty()) {
if(B.Fr()!=B.Bk())
return;
ans[i]=ans[n-i+1]=2;
B.Pb(),B.Pf();
} else {
if(A.Sz()>1 && A.Fr()==A.Bk())
ans[i]=ans[n-i+1]=1,A.Pb(),A.Pf();
else if(A.Bk()==B.Fr())
ans[i]=1,ans[n-i+1]=2,A.Pb(),B.Pf();
else if(A.Fr()==B.Bk())
ans[i]=2,ans[n-i+1]=1,A.Pf(),B.Pb();
else if(B.Sz()>1 && B.Fr()==B.Bk())
ans[i]=ans[n-i+1]=2,B.Pb(),B.Pf();
else return;
}
}
fl=1;
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d",&n),n<<=1;
for(int i=1;i<=n;i++) {
scanf("%d",&x[i]);
}
ans[n]=1;
fl=0;
ans[1]=1;
for(int i=2;i<=n;i++)
if(x[i]==x[1]) {
p=i; break;
}
make(1);
if(!fl) {
ans[1]=2;
for(int i=1;i<n;i++)
if(x[i]==x[n]) {
p=i; break;
}
make(n);
}
if(!fl)puts("-1");
else {
for(int i=1;i<=n;i++) {
if(ans[i]==1)putchar('L');
else putchar('R');
}
puts("");
}
}
}
T4
What?
看懂大意后直接再見
總結
很好——暴力沒有掛,至少能有分
我* —— 實現上的失誤,還是代碼實現能力差
大總結
- 代碼實現能力弱
- 思維不夠發散,一些結論不難的題想不到
- 考試的心態不夠好,過於心急,導致半天一籌莫展
過去的都過去了,希望本蒟蒻以后能專注於訓練思維、代碼實現
noip 2021 保佑