A - Doors in the Center
- 如果\(n\)为奇数,就依次输出\(\frac{n-1}{2}\)个
-
、\(1\)个=
、\(\frac{n-1}{2}\)个-
。 - 如果\(n\)为偶数,就依次输出\(\frac{n}{2}-1\)个
-
、\(2\)个=
、\(\frac{n}{2}-1\)个-
。
时间复杂度\(O(n)\)。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
signed main(){cin>>n;if(n&1){for(int i=1;i<=n/2;i++) cout<<"-";cout<<"=";for(int i=1;i<=n/2;i++) cout<<"-";}else{for(int i=1;i<n/2;i++) cout<<"-";cout<<"==";for(int i=1;i<n/2;i++) cout<<"-";}return 0;
}
B - Full House 3
统计每个值出现的次数,输出Yes
\(\iff\)最大次数\(\ge 3\)且次大次数\(\ge 2\)。
代码为了方便对桶数组进行了排序,时间复杂度为\(O(n+V\log V)\)。也可以做到\(O(n)\)。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int b[14];
signed main(){for(int i=0,a;i<7;i++) cin>>a,b[a]++;sort(b+1,b+1+13);if(b[13]>=3&&b[12]>=2) cout<<"Yes\n";else cout<<"No\n";return 0;
}
C - Uniqueness
可以用map
等数据结构作为桶,或者离散化后直接用数组作为桶。
统计所有出现次数为\(1\)的\(a_i\),将最大的\(a_i\)所对应的\(i\)记录并输出即可。
代码时间复杂度\(O(n)\)。如果用map
或者离散化则是\(O(n\log n)\)。
点击查看代码
#include<bits/stdc++.h>
#define N 300010
using namespace std;
unordered_map<int,int> ma;
int n,a[N],maxx,maxpos=-1;
signed main(){cin>>n;for(int i=1;i<=n;i++) cin>>a[i],ma[a[i]]++;for(int i=1;i<=n;i++){if(ma[a[i]]==1&&a[i]>=maxx){maxx=a[i],maxpos=i;}}cout<<maxpos;return 0;
}
D - Bonfire
让烟静止下来。
风向右吹,可以看做人和篝火同时向左走,且篝火在原来的位置留下了一团烟。
这样一来烟就是静止不动的了。遍历每一个操作,同时用set
记录篝火走过的每一个位置,如果某次操作后人走到了此前篝火曾走过的位置,就输出1
。
代码时间复杂度\(O(n\log n)\)。如果把下标压到一个整数里再用哈希表也可以做到\(O(n)\),不过没必要。
点击查看代码
#include<bits/stdc++.h>
#define N 200010
using namespace std;
int n,r,c,x,y;
string s;
set<pair<int,int>> vis;
signed main(){cin>>n>>r>>c>>s;vis.insert({0,0});for(char i:s){if(i=='N') x++,r++;else if(i=='S') x--,r--;else if(i=='E') y--,c--;else if(i=='W') y++,c++;vis.insert({x,y});cout<<vis.count({r,c});}return 0;
}
很有意思的思维题。
E - Tree Game
不难发现,最后游戏结束时,\(G\)一定变成了一个完全二分图。
由于所给的图是树,所以将它看做二分图时,两个组的节点是固定的。从而两人的总操作数也是固定的,即为\(x\times y-(n-1)\),其中\(x,y\)是两组的节点数。
如果\(x\times y-(n-1)\)为奇数则选择先手,否则选择后手。
接下来每次己方操作,就选一条对方没连过的边输出即可。
时间复杂度\(O(n^2)\)。
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define N 110
using namespace std;
int n,cntw;
bitset<N> vis[N];
bitset<N> col;
vector<int> G[N];
void dfs(int u,int fa){cntw+=col[u];for(int i:G[u]){if(i==fa) continue;col[i]=col[u]^1,dfs(i,u);}
}
signed main(){cin>>n;for(int i=1,u,v;i<n;i++){cin>>u>>v;G[u].emplace_back(v);G[v].emplace_back(u);vis[u][v]=1;}dfs(1,0);int t=cntw*(n-cntw)-(n-1),u,v;if(t&1){cout<<"First"<<endl;}else{cout<<"Second"<<endl;cin>>u>>v;if(u==-1) exit(0);vis[u][v]=1;}for(int i=1;i<n;i++){for(int j=i+1;j<=n;j++){if(!vis[i][j]&&col[i]!=col[j]){cout<<i<<" "<<j<<endl;cin>>u>>v;if(u==-1) exit(0);vis[u][v]=1;}}}return 0;
}
作为E实在有点水了。
F - ABCBA
当我们找到一个\(S\)的回文后缀,将这个后缀之前的东西翻转过来拼在\(S\)末尾,这样一个合法的回文串\(S'\)就构造成了。
为了使\(S'\)最短,我们要寻找\(S\)的最长回文后缀。
可以使用Manacher算法求解,不过我还不会,所以就用字符串哈希了(
求法比较自然,就是根据回文串长度
时间复杂度均为\(O(n)\)。
点击查看代码
#include<bits/stdc++.h>
#define ull unsigned long long
#define N 500010
#define B 131
using namespace std;
string s;
int n;
ull ds[N],dr[N],powb[N];
ull f(int l,int r){return ds[r]-ds[l-1]*powb[r-l+1];
}
ull fr(int l,int r){swap(l,r),l=n-l+1,r=n-r+1;return dr[r]-dr[l-1]*powb[r-l+1];
}
signed main(){powb[0]=1;for(int i=1;i<N;i++) powb[i]=powb[i-1]*B;cin>>s;n=s.size(),s=' '+s;for(int i=1;i<=n;i++) ds[i]=ds[i-1]*B+s[i];for(int i=1;i<=n;i++) dr[i]=dr[i-1]*B+s[n-i+1];int i;for(i=1;i<=n;i++){if(f(i,n)==fr(i,n)){for(char j:s) if(j!=' ') cout<<j;for(int j=i-1;j>=1;j--) cout<<s[j];break;}}return 0;
}
作为F实在有点水过头了……
而且放\(\bf O(n^2)\)暴力过了!?
G - Not Only Tree Game
再补。