CF 979 Review
喜聞樂見的C題不鍛鍊碼力的場,可惜早早地做完了C之後就開始想D,到最後知道怎麼做了,但是寫不來程式碼。
實際上還是腦子不夠好使,想不出來簡單的寫法;只有複雜的思路,但卻沒有相應的碼力。
A
分析
很明顯的一個貪心,注意考慮一下邊界條件即可。
Code
#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void re(T &x)
{
x=0;int f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
x*=f;
}
template<typename T>inline void wr(T x)
{
if(x<0)putchar('-'),x=-x;
if(x>9)wr(x/10);
putchar(x%10^48);
}
inline void out(int x){wr(x),putchar('\n');}
int n,m,T;
int main()
{
re(T);
int tmp;
while(T--)
{
re(n);
int mx=-1,mn=1000000,s=0;
for(int i=1;i<=n;++i)
{
cin>>tmp;s+=tmp;
mx=max(mx,tmp);
mn=min(mn,tmp);
}
out(n*(mx-mn)-mx+mn);
}
return 0;
}
B
分析
推式子題,用到了組合數的求和公式,也還是比較容易,最後得到的結論就是輸出 \(n-1\) 個 \(0\) ,注意特判一下 \(n=1\) 的情況即可。
Code
#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void re(T &x)
{
x=0;int f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
x*=f;
}
template<typename T>inline void wr(T x)
{
if(x<0)putchar('-'),x=-x;
if(x>9)wr(x/10);
putchar(x%10^48);
}
inline void out(int x){wr(x),putchar('\n');}
int n,m,T;
int main()
{
re(T);
while(T--)
{
re(n);
if(n==1){puts("0");}
else
{
for(int i=1;i<=n-1;++i)putchar('0');
puts("1");
}
}
return 0;
}
C
很好的一道思維題博弈論
分析
首先如果端位有 \(1\) 那麼肯定是先手贏。
開始的想法是,對於兩人中的任意一個人來說,在 \(11\) 中間進行操作都是沒有意義的,所以整個串可以縮寫為 \(010101...1010\) 的形式。
這樣看來那麼先手不論下在哪裡,後手都可以使得先手這一步變得無效,最後一定是後手贏。
交上去發現 WA 了。
問題在於縮寫的這個過程並不恰當。
假設有一個 \(0110\) 的串,如果先手在最中間放一個,那麼後手無論堵哪一個,下一個先手都可以再放一個 "|" 使得有一個 \(1\) 被完全包含,也就是最終的答案一定是 \(1\) 。推而廣之,只要有若干個連續的 \(1\) ,就一定能贏。
Code
#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void re(T &x)
{
x=0;int f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
x*=f;
}
template<typename T>inline void wr(T x)
{
if(x<0)putchar('-'),x=-x;
if(x>9)wr(x/10);
putchar(x%10^48);
}
inline void out(int x){wr(x),putchar('\n');}
int n,m,T;
char s[200010];
int main()
{
re(T);
while(T--)
{
re(n);
scanf("%s",&s);
if(s[0]=='1'||s[n-1]=='1')
{
puts("YES");
goto A;
}
else
{
for(int i=1;i<n;++i)
{
if(s[i]==s[i-1]&&s[i]=='1')
{
puts("YES");
goto A;
}
}
}
puts("NO");
A:;
}
return 0;
}
D
分析
很早就推出了一個結論:任意的 \(RRRRR...RLLLLL...L\) 一定可以透過氣泡排序的原理來使得整個子序列達到有序。
言下之意就是,\(LR\) 對應的一定是一個斷點 ,左邊無法往右,右邊無法往左,我們不妨用左邊的 \(L\) 對應的下標來代表這個斷點所在的位置。
想讓這個排列變得有序,我們必須讓所有元素回到其對應的位置上,設一個元素 \(x\) 現在的位置是 \(pos\) ,那麼它應該回到 \(x\) 的下標上。
也就是說我們需要 從 \(idx\rightarrow x\) 的路徑上是不間斷的,在我們對斷點的定義下,要求 \(idx\rightarrow(x-1)\) 的路徑中所有下標都不能是斷點。
並且對於每一個元素都必須有以上性質成立。
那麼我們可以維護有哪些點被至少一條路徑依賴,並把其中所有斷點丟進一個set中,在修改操作的時候動態地進行插入和刪除。
如果在操作過後set裡面沒有斷點,也就是說所有路徑都是暢通的,這時候答案就是yes,否則就是no。
盲區
scanf字串的時候不要加取地址!!!
Code
#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void re(T &x)
{
x=0;int f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
x*=f;
}
template<typename T>inline void wr(T x)
{
if(x<0)putchar('-'),x=-x;
if(x>9)wr(x/10);
putchar(x%10^48);
}
inline void out(int x){wr(x),putchar('\n');}
int n,m,T,q,pos;
char upd[200010];
int a[200010],s[200010];
int main()
{
re(T);
while(T--)
{
re(n),re(q);
for(register int i=1;i<=n;++i)s[i]=0;
for(register int i=1;i<=n;++i)
{
re(a[i]);
s[min(i,a[i])]++;
s[max(i,a[i])]--;
}
scanf("%s",upd+1);
set<int> err;
for(register int i=1;i<=n;++i)
{
s[i]+=s[i-1];
if(upd[i]=='L'&&upd[i+1]=='R'&&i!=n&&s[i])
err.insert(i);
}
// for(register int i=1;i<=n;++i)cout<<s[i]<<' ';
// cout<<endl;
auto modify=[&](int pos)
{
if(upd[pos]=='L')
{
if(upd[pos+1]=='R'&&pos!=n&&err.count(pos))
err.erase(pos);
if(upd[pos-1]=='L'&&pos!=1&&s[pos-1])
err.insert(pos-1);
upd[pos]='R';
}
else
{
if(upd[pos-1]=='L'&&pos!=1&&err.count(pos-1))
err.erase(pos-1);
if(upd[pos+1]=='R'&&pos!=n&&s[pos])
err.insert(pos);
upd[pos]='L';
}
};
while(q--)
{
re(pos);
modify(pos);
puts(err.empty()?"YES":"NO");
}
}
return 0;
}
/*
3
5 3
1 4 2 5 3
RLRLL
2
4
3
8 5
1 5 2 4 8 3 7 6
RRLLRRRL
4
3
5
3
4
6 2
1 2 3 4 5 6
RLRLRL
4
5
*/
總結
非常緊迫的一個問題就是要強化自己的程式碼實現能力,可以去學一些巧妙的stl用法等。