牛客练习赛 57——manacher算法 树形dp?
A - Tic-Tac-Toe
直接考慮每個人8種贏的情況即可。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<iostream> #include<algorithm> using namespace std; const int N=5; char g[N][N]; int main() {//IO;int T=1;cin>>T;while(T--){for(int i=1;i<=3;i++) cin>>g[i]+1;bool ok1=0,ok2=0;if(g[1][1]=='A'&&g[1][2]=='A'&&g[1][3]=='A') ok1=1;if(g[2][1]=='A'&&g[2][2]=='A'&&g[2][3]=='A') ok1=1;if(g[3][1]=='A'&&g[3][2]=='A'&&g[3][3]=='A') ok1=1;if(g[1][1]=='A'&&g[2][1]=='A'&&g[3][1]=='A') ok1=1;if(g[1][2]=='A'&&g[2][2]=='A'&&g[3][2]=='A') ok1=1;if(g[1][3]=='A'&&g[2][3]=='A'&&g[3][3]=='A') ok1=1;if(g[1][1]=='A'&&g[2][2]=='A'&&g[3][3]=='A') ok1=1;if(g[1][3]=='A'&&g[2][2]=='A'&&g[3][1]=='A') ok1=1;if(g[1][1]=='B'&&g[1][2]=='B'&&g[1][3]=='B') ok2=1;if(g[2][1]=='B'&&g[2][2]=='B'&&g[2][3]=='B') ok2=1;if(g[3][1]=='B'&&g[3][2]=='B'&&g[3][3]=='B') ok2=1;if(g[1][1]=='B'&&g[2][1]=='B'&&g[3][1]=='B') ok2=1;if(g[1][2]=='B'&&g[2][2]=='B'&&g[3][2]=='B') ok2=1;if(g[1][3]=='B'&&g[2][3]=='B'&&g[3][3]=='B') ok2=1;if(g[1][1]=='B'&&g[2][2]=='B'&&g[3][3]=='B') ok2=1;if(g[1][3]=='B'&&g[2][2]=='B'&&g[3][1]=='B') ok2=1;if(ok1&&ok2) cout<<"invalid\n";else if(ok1) cout<<"Yes\n";else if(ok2) cout<<"No\n";else cout<<"draw\n";}return 0; }B - 打 boss
如果第一次都能打死就不考慮回復(fù)血的情況
如果第一次打不死并且回血不少于掉血肯定永遠(yuǎn)打不死
人死之前最多能攻擊?h1a2?\lceil\frac{h_1}{a_2} \rceil?a2?h1???次,如果死之前打不死(需要干掉h2+m?h1a2?1?h2+m\lceil\frac{h_1}{a_2}-1 \rceilh2+m?a2?h1???1?血量)那么就打不死,否則能打死。
C - 裝貨物
搜索渣渣。沒經(jīng)歷過偏分的oi沒能成為搜索king
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=30; ll w[N]; int n,m,W; ll now[N]; bool ok; void dfs(int u,int cnt) {if(ok) return;//這個優(yōu)化直接讓我過了if(u>n){ok=1;return;}for(int i=1;i<=cnt;i++){if(now[i]+w[u]<=W){now[i]+=w[u];dfs(u+1,cnt);now[i]-=w[u];}}if(w[u]<=W&&cnt+1<=m){now[cnt+1]=w[u];dfs(u+1,cnt+1);now[cnt+1]-=w[u];} } int main() {IO;int T=1;cin>>T;while(T--){cin>>n>>m>>W;for(int i=1;i<=n;i++) cin>>w[i];sort(w+1,w+1+n);reverse(w+1,w+1+n);ok=0;memset(now,0,sizeof now);dfs(1,0);if(ok) cout<<"Yes\n";else cout<<"No\n";}return 0;}D - 回文串
學(xué)了一下manacher算法,模板++
用manacher算法求后p[i]-1即表示原字符串回文序列長度,而且經(jīng)過對字符串進(jìn)行添加*操作后最終每個回文字符串的最左或右端一定是*。
對于本題需求不相交且長度和最大的非空回文子串,我們可以嘗試枚舉劃分點,左邊最長的回文子串+右邊最長的回文子串(預(yù)處理前綴后綴即可)即可求出。
注意:由于每個回文字符串的最左或右端一定是*,一定不會出現(xiàn)相交的情況。
非空想想不難知道只有在整個字符串都是回文串的情況下非空才會和不非空的結(jié)果不一樣(其他情況非空的結(jié)果一定更優(yōu))。我們需要特判整個字符串是回文串的情況。
E - 劃分樹
大佬題解
F有點懵,先記下來。
要加油哦~
總結(jié)
以上是生活随笔為你收集整理的牛客练习赛 57——manacher算法 树形dp?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大学还教游戏设计大学游戏设计专业课程有哪
- 下一篇: ACL Beginner Contest