[CF1941D] Rudolf and the Ball Game 的题解
题目大意
有 个人投球,投了 次。第 次投球时想左、右或者随便一个方向投掷 个人。从第 个人开始投球,询问最后球在最后有可能在谁的手里。
其中 。
思路
如果遇到方向不确定的情况,可以暴力的考虑直接枚举。考虑在最坏的情况下,全部的投球肯能方向不确定,那么我们就需要枚举 ,因为这些人一共会接到 次球。
在一轮投球中只有 个人但是却接到了 次球,可见一个人可能会多次接到球。因为在一轮中,不论一个人接到多少次球那么效果其实都是一样的。
所以设 表示在第 次投球时,第 个人是否有可能拿到球。假设 表示第 个人移动 后的位置,发么状态转移方程为
AC Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1005;
int n,m,a[N],f[N][N],x;
char c[N];
void solve(){
cin>>n>>m>>x;
for(int i=1;i<=m;i++) cin>>a[i]>>c[i];
for(int i=0;i<=m;i++) for(int j=0;j<=n;j++) f[i][j]=0;
f[0][x-1]=1;
for(int i=1;i<=m;i++){
for(int j=0;j<n;j++){
if(c[i]=='0'||c[i]=='?') f[i][(j+a[i])%n]|=f[i-1][j];
if(c[i]=='1'||c[i]=='?') f[i][(j-a[i]+n)%n]|=f[i-1][j];
}
}
vector<int> ans;
for(int i=0;i<n;i++) if(f[m][i]) ans.push_back(i+1);
cout<<ans.size()<<'\n';
for(int i:ans) cout<<i<<' ';
cout<<'\n';
}signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T;cin>>T;
while(T--) solve();
return 0;
}