比赛链接:Sky Inc, Programming Contest 2023(AtCoder Beginner Contest 289) - AtCoder
A - flip
void solve()
{
string s;
cin>>s;
int len = s.size();
for(int i=0;i<len;i++){
if(s[i]=='0') cout<<"1";
else cout<<"0";
}
}
B - V
1~n被分为若干部分,每个部分需要逆序输出。如1 2 3 4 5分成了(1 2 3)和(4 5),那么输出的结果是3 2 1 5 4。用邻接矩阵存储连接在一起的数字,查找时像dfs一样,输出时利用栈的特点实现逆序输出。
vector<int>v[100+5];
bool vis[100+5];
void solve()
{
int n,m;
cin>>n>>m;
while(m--){
int val;
cin>>val;
v[val].push_back(val+1);
}
for(int i=1;i<=n;i++){
stack<int>sta;
if(!vis[i]){
int now = i;
sta.push(i);
while(v[now].size()){
now = v[now][0];
sta.push(now);
vis[now] = true;
}
while(!sta.empty()){
cout<<sta.top()<<" ";
sta.pop();
}
}
}
}
C - Coverage
看数据量挺小的就用dfs做了,假设有n个集合,从1~n每个集合分为选与不选两种情况,在搜索层数到达n层时检查是否符合题意得出答案。可以利用set的去重功能检查是否包含了1~n的数。
set<int>se[10+2];
int ans;
int n,m;
void dfs(int u,set<int>check,bool flag)
{
if(u>m) return ;
if(flag){
for(auto it:se[u]){
check.insert(it);
}
}
if(u==m && check.size()==n) ans++;
dfs(u+1,check,true);
dfs(u+1,check,false);
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=m;i++){
int t;
cin>>t;
while(t--){
int x;
cin>>x;
se[i].insert(x);
}
}
set<int>check;
dfs(1,check,true);
dfs(1,check,false);
cout<<ans<<endl;
}
D - Step Up Robot
上题用了dfs写导致看见这题也想试试dfs+剪枝能不能过,TLE了8个数据,这里不知道怎么用记忆化,那就用dp好了,f[i]表示能否到达第i级阶梯,从头到尾线性滚一边,检查当前位置能不能由上一个位置转移过来,最终时间复杂度为O(n*x),下面那个版本更符合“常规的”写法。
int n,m;
int goal;
const int N = 100010;
int v[10+2];
int f[N];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>v[i];
cin>>m;
for(int i=1;i<=m;i++){
int e;
cin>>e;
f[e] = -1;
}
cin>>goal;
f[0] = 1;
for(int i=1;i<=goal;i++){
if(f[i]>=0){
for(int j=1;j<=n;j++){
//i-v[j]检查从上一个转移过来的位置
if(i-v[j]>=0 && f[i-v[j]]>0){ //可以走到上一个位置并且那个位置没有地雷
f[i] = 1;
}
}
}
}
if(f[goal]>0) puts("Yes");
else puts("No");
}
int n,m;
int goal;
const int N = 100010;
bool track[N];
int v[10+2];
int f[N];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>v[i];
cin>>m;
for(int i=1;i<=m;i++){
int e;
cin>>e;
track[e] = true;
}
cin>>goal;
f[0] = 1;
for(int i=1;i<=goal;i++){
for(int j=1;j<=n;j++){
if(track[i]) break;
if( i>=v[j]) f[i] |= f[i-v[j]];
}
}
if(f[goal]) puts("Yes");
else puts("No");
}