类似牛客小白月赛的一道dp https://ac.nowcoder.com/acm/contest/75771/D
这个题目也是一个动态规划问题,dp[i][j]代表第i次传到j的位置,我们先判断dp[i-1][j]是否可以到达,到达就更新j点可以传的位置,如果为‘0或’ 1‘直接分别计算,为’?‘需要都标记为1。注意这个问题的dp[i][0]代表的是第i次是否传到n号位置。使用0 - n-1 替换1 - n,便于更新位置。
#include<bits/stdc++.h> #define int long long typedef unsigned long long ull; typedef long long ll; using namespace std; const int N = 1e3 + 10; const int mod = 1e9 + 7; int dp[1010][1010]; void solve(){ int n,m,x; cin>>n>>m>>x; for (int i = 0; i <= m; ++i) { for (int j = 0; j <= n; ++j) { dp[i][j] = 0; } } dp[0][x%n] = 1; for (int i = 1; i <= m; ++i) { int r; char c; cin>>r>>c; for (int j = 0; j < n; ++j) { if(dp[i-1][j] != 1) continue; if(c == '0') dp[i][(j+r) % n] = 1; if(c == '1') dp[i][(j + n - r) % n] = 1; if(c == '?'){ dp[i][(j+r) % n] = 1; dp[i][(j + n - r) % n] = 1; } } } int num = 0; for (int i = 0; i < n; ++i) { if(dp[m][i] == 1) num++; } cout<<num<<endl; for (int i = 1; i < n; ++i) { if(dp[m][i] == 1){ cout<<i<<" "; } } if(dp[m][0] == 1) cout<<n; cout<<endl; } signed main(){ ios::sync_with_stdio(false); cin.tie(NULL),cout.tie(NULL); int t = 1; cin>>t; while(t--){ solve();//1 2 3 4 5 } return 0 ; }