「csp模拟」模拟测试16
T1:阴阳
- 正解不会。。。
fdasds
#include <bits/stdc++.h>
using namespace std;
#define cle(a) memset(a, 0, sizeof(a))
inline int read() {
int k = 0, f = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for (; isdigit(ch); ch = getchar()) k = k * 10 + ch - '0';
return k * f;
}
const int mod = 1e9 + 7, maxn = 1e3 + 100;
int n, m, ans = 0;
int f[maxn][maxn];
int jl[maxn][maxn], a[maxn][maxn];
int jlh1b[6], jll1b[6];
int jlh2b[6], jll2b[6];
int jlh1e[6], jll1e[6];
int jlh2e[6], jll2e[6];
int vis[6][6];
void dfs1(int x, int y, int col) {
if (x < 1 || y < 1 || x > n || y > m || vis[x][y] == 1) return;
if (jl[x][y] == col) {
vis[x][y] = 1;
dfs1(x + 1, y, col);
dfs1(x, y + 1, col);
dfs1(x - 1, y, col);
dfs1(x, y - 1, col);
}
}
void dfs(int cur, int cnt) {
if (cur == n * m + 1) {
cle(jlh1b), cle(jll1b);
cle(jlh2b), cle(jll2b);
cle(jlh1e), cle(jll1e);
cle(jlh2e), cle(jll2e);
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++) {
int flag = 0;
for (int j = 1; j <= m; j++) {
if (jl[i][j] == 1) jlh1e[i] = j;
if (jl[i][j] == 2) jlh2e[i] = j;
if (jl[i][j] == 1) jll1e[j] = i;
if (jl[i][j] == 2) jll2e[j] = i;
if (jl[i][j] == 1 && jlh1b[i] == 0) jlh1b[i] = j;
if (jl[i][j] == 2 && jlh2b[i] == 0) jlh2b[i] = j;
if (jl[i][j] == 1 && jll1b[j] == 0) jll1b[j] = i;
if (jl[i][j] == 2 && jll2b[j] == 0) jll2b[j] = i;
}
}
int now = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (!vis[i][j]) dfs1(i, j, jl[i][j]), now++;
if (now > 2) return ;
}
}
int col = jl[1][1];
int line = 1, row = 1;
for (int i = 1; i <= m; i++) {
if (jll1b[i] == 0) continue;
if (jll2b[i] == 0) continue;
for (int j = jll1b[i]; j <= jll1e[i]; j++) if (jl[j][i] != 1) return;
for (int j = jll2b[i]; j <= jll2e[i]; j++) if (jl[j][i] != 2) return;
}
for (int i = 1; i <= n; i++) {
if (jlh1b[i] == 0) continue;
if (jlh2b[i] == 0) continue;
for (int j = jlh1b[i]; j <= jlh1e[i]; j++) if (jl[i][j] != 1) return;
for (int j = jlh2b[i]; j <= jlh2e[i]; j++) if (jl[i][j] != 2) return;
}
ans ++;
ans %= mod;
return;
}
int row = cur % m, line = cur / m + 1;
if (row == 0) row = m;
if (cur % m == 0) line--;
if (a[line][row] == 1) dfs(cur + 1, cnt);
else if (a[line][row] == 2) dfs(cur + 1, cnt + 1);
else {
jl[line][row] = 1; dfs(cur + 1, cnt); jl[line][row] = 0;
jl[line][row] = 2; dfs(cur + 1, cnt + 1); jl[line][row] = 0;
}
}
signed main() {
freopen("yinyang.in", "r", stdin), freopen("yinyang.out", "w", stdout);
n = read(), m = read();
int cnt = 0, cnt1 = 0;
for (int i = 1; i <= n; i++) {
char s[maxn]; scanf("%s", s + 1);
for (int j = 1; j <= m; j++) {
if (s[j] == 'B') a[i][j] = jl[i][j] = 1, cnt1 ++;
else if (s[j] == 'W') a[i][j] = jl[i][j] = 2, cnt++;
else a[i][j] = 3;
}
}
if (m < 5 && n < 5) return dfs(1, 0), cout << ans << endl, 0;
for (int i = 1; i <= n; i++) f[i][1] = i * 2;
for (int i = 1; i <= m; i++) f[1][i] = i * 2;
for (int i = 2; i <= n; i++)
for (int j = 2; j <= m; j++)
f[i][j] = (f[i - 1][j] + f[i][j - 1] + (i + j - 1) * 2) % mod;
cout << f[n][m] % mod << endl;
}
60分暴力代码
#include <bits/stdc++.h>
using namespace std;
#define cle(a) memset(a, 0, sizeof(a))
inline int read() {
int k = 0, f = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for (; isdigit(ch); ch = getchar()) k = k * 10 + ch - '0';
return k * f;
}
const int mod = 1e9 + 7, maxn = 1e3 + 100;
int n, m, ans = 0;
int f[maxn][maxn];
int jl[maxn][maxn], a[maxn][maxn];
int jlh1b[6], jll1b[6];
int jlh2b[6], jll2b[6];
int jlh1e[6], jll1e[6];
int jlh2e[6], jll2e[6];
int vis[6][6];
void dfs1(int x, int y, int col) {
if (x < 1 || y < 1 || x > n || y > m || vis[x][y] == 1) return;
if (jl[x][y] == col) {
vis[x][y] = 1;
dfs1(x + 1, y, col);
dfs1(x, y + 1, col);
dfs1(x - 1, y, col);
dfs1(x, y - 1, col);
}
}
void dfs(int cur, int cnt) {
if (cur == n * m + 1) {
cle(jlh1b), cle(jll1b);
cle(jlh2b), cle(jll2b);
cle(jlh1e), cle(jll1e);
cle(jlh2e), cle(jll2e);
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++) {
int flag = 0;
for (int j = 1; j <= m; j++) {
if (jl[i][j] == 1) jlh1e[i] = j;
if (jl[i][j] == 2) jlh2e[i] = j;
if (jl[i][j] == 1) jll1e[j] = i;
if (jl[i][j] == 2) jll2e[j] = i;
if (jl[i][j] == 1 && jlh1b[i] == 0) jlh1b[i] = j;
if (jl[i][j] == 2 && jlh2b[i] == 0) jlh2b[i] = j;
if (jl[i][j] == 1 && jll1b[j] == 0) jll1b[j] = i;
if (jl[i][j] == 2 && jll2b[j] == 0) jll2b[j] = i;
}
}
int now = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (!vis[i][j]) dfs1(i, j, jl[i][j]), now++;
if (now > 2) return ;
}
}
int col = jl[1][1];
int line = 1, row = 1;
for (int i = 1; i <= m; i++) {
if (jll1b[i] == 0) continue;
if (jll2b[i] == 0) continue;
for (int j = jll1b[i]; j <= jll1e[i]; j++) if (jl[j][i] != 1) return;
for (int j = jll2b[i]; j <= jll2e[i]; j++) if (jl[j][i] != 2) return;
}
for (int i = 1; i <= n; i++) {
if (jlh1b[i] == 0) continue;
if (jlh2b[i] == 0) continue;
for (int j = jlh1b[i]; j <= jlh1e[i]; j++) if (jl[i][j] != 1) return;
for (int j = jlh2b[i]; j <= jlh2e[i]; j++) if (jl[i][j] != 2) return;
}
ans ++;
ans %= mod;
return;
}
int row = cur % m, line = cur / m + 1;
if (row == 0) row = m;
if (cur % m == 0) line--;
if (a[line][row] == 1) dfs(cur + 1, cnt);
else if (a[line][row] == 2) dfs(cur + 1, cnt + 1);
else {
jl[line][row] = 1; dfs(cur + 1, cnt); jl[line][row] = 0;
jl[line][row] = 2; dfs(cur + 1, cnt + 1); jl[line][row] = 0;
}
}
signed main() {
freopen("yinyang.in", "r", stdin), freopen("yinyang.out", "w", stdout);
n = read(), m = read();
int cnt = 0, cnt1 = 0;
for (int i = 1; i <= n; i++) {
char s[maxn]; scanf("%s", s + 1);
for (int j = 1; j <= m; j++) {
if (s[j] == 'B') a[i][j] = jl[i][j] = 1, cnt1 ++;
else if (s[j] == 'W') a[i][j] = jl[i][j] = 2, cnt++;
else a[i][j] = 3;
}
}
if (m < 5 && n < 5) return dfs(1, 0), cout << ans << endl, 0;
for (int i = 1; i <= n; i++) f[i][1] = i * 2;
for (int i = 1; i <= m; i++) f[1][i] = i * 2;
for (int i = 2; i <= n; i++)
for (int j = 2; j <= m; j++)
f[i][j] = (f[i - 1][j] + f[i][j - 1] + (i + j - 1) * 2) % mod;
cout << f[n][m] % mod << endl;
}
T2:简单的序列
dp,第一位表示左面的长度,第二位表示左面的左括号数目,具体解析见代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read() {
int k = 0, f = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for (; isdigit(ch); ch = getchar()) k = k * 10 + ch - '0';
return k * f;
}
const int mod = 1e9 + 7, maxn = 1e6 + 1000;
int jc[maxn], ny[maxn], jcny[maxn];
inline int qpow(int x, int y) {
int ans = 1;
for (; y; y >>= 1, x = x * x % mod) if (y & 1) ans = ans * x % mod;
return ans;
}
int C(int n, int m) {
return jc[n] * jcny[m] % mod * jcny[n - m] % mod;
}
signed main() {
freopen("bracket.in", "r", stdin), freopen("bracket.out", "w", stdout);
jc[0] = ny[0] = ny[1] = jcny[0] = jcny[1] = 1;
int n = read(), m = read();
for (int i = 1; i <= n; i++) jc[i] = jc[i - 1] * i % mod;
for (int i = 2; i <= n; i++) ny[i] = (mod - mod / i) * ny[mod % i] % mod;
for (int i = 2; i <= n; i++) jcny[i] = jcny[i - 1] * ny[i] % mod;
char s[maxn]; scanf("%s", s + 1);
int tot = 0, maxx = 0, cntl = 0, cntr = 0;
for (int i = 1; i <= m; i++) {
if (s[i] == '(') tot --, cntl ++;
if (s[i] == ')') tot ++, cntr ++;
if (tot > maxx) maxx = tot;
}
int ans = 0;
for (int i = 0; i <= n - m; i++) {
for (int j = (i + maxx + 1) / 2; j <= i; j++) {
int now = cntl + j;
int cur = n / 2 - now; // 右边的左括号数目,即向上走的步数
ans = (ans + ((C(i, j) - C(i, j + 1) + mod) % mod) * ((C(n - i - m, cur) - C(n - i - m, cur - 1) + mod) % mod) % mod) % mod;
// (C(i, j) - C(i, j + 1) + mod) % mod) : 左边在 i 的长度中选择 j 个左括号的方案数目, 坐标系上起点为(0, 0),终点为 (i, (j - (i - j))) => (i, 2 * j - i) ,关于 ( y = -1 )的对称点为 (i, i - 2 * j - 2),
// 令 x 为向下走的步数,则 (i - x) 为向上走的步数,所以 (x - (i - x)) == (i - 2 * j - 2), 解得 x = (j + 1),所以左边方案数即可得。
// (C(n - i - m, cur) - C(n - i - m, cur - 1) : cur 为右边要选择的左括号数目,(总共 n/2 个左括号,左边一共有了 (cntl + j) 个左括号),起点为 (0, 一个数),终点为(n - m - i, 0), 对称点为 (n - m - i, -2),
// 从其中选择 cur 步往上走, 则有 (n - i - m - cur) 步往下走, 所以起点为 (0, n - i - m - cur - cur) 终点为 (n - i - m, -2), 还是令向上走的步数为 x,
// 所以 (x - (n - i - m - x)) == (0, -2 - n + i + m + 2 * cur) , 解得 x = (cur - 1), 所以右边方案数就知道了,最后左边乘右边就对了。。。
}
}
cout << ans % mod << endl;
}
T3:简单的期望
正解dp,转移很复杂,这里只给出暴力代码,要打好概率dp的暴力!!!
#include <bits/stdc++.h>
using namespace std;
#define int long long
inline int read() {
int k = 0, f = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for (; isdigit(ch); ch = getchar()) k = k * 10 + ch - '0';
return k * f;
}
int x, n; double p, ans;
void dfs(int cnt, double now, double cur) {
if (cnt == n) {
int curans = 0;
int x = (int)now;
while (x % 2 == 0) curans ++, x /= 2;
ans += 1.0 * curans * cur;
return;
}
dfs(cnt + 1, now * 2, cur * p);
dfs(cnt + 1, now + 1, cur * (1 - p));
}
signed main() {
freopen("exp.in","r",stdin), freopen("exp.out","w",stdout);
x = read(), n = read(); p = 1.0 * read() / 100;
dfs(0, x, 1);
printf("%.10lf\n", ans);
return 0;
}