A.On The Way to Lucky Plaza (数论)
题意:m个店 每个店可以买一个小球的概率为p
求恰好在第m个店买到k个小球的概率
题解:求在前m-1个店买k-1个球再*p就好了 最开始没太懂输出什么意思
其实就是p*q的逆元的意思 因为概率是三位小数于是对他*1000*1000的逆元处理
还要加个eps 因为0.005浮点数由于不确定性可能存的0.0050001或者0.00499999

#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod = 1000000007; ll ny[100005]; ll pow_mod(ll x, ll y) { ll res = 1; while(y) { if(y & 1) res = res * x % mod; x = x * x % mod; y >>= 1; } return res % mod; } int main() { ll n, m, k; scanf("%lld%lld%lld", &m, &n, &k); for(ll i = 1; i <= 100000; i++) ny[i] = pow_mod(i, mod - 2LL); double pp; scanf("%lf", &pp); ll p = 1000 * pp + 1e-8; ll ans = 1; for(int i = 1; i <= k - 1; i++) ans = ans * ny[i] % mod; for(ll i = 1; i <= k - 1; i++) ans = ans * (n - i) % mod; for(int i = 1; i <= k; i++) ans = ans * p % mod; for(int i = 1; i <= n - k; i++) ans = ans * (1000 - p) % mod; for(int i = 1; i <= n; i++) ans = ans * ny[1000] % mod; printf("%lld ", ans); return 0; }
B.So You Think You Can Count?(水DP)

#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod = 1000000007; char s[10005]; int vis[10]; ll dp[10005]; int main() { int n; scanf("%d", &n); scanf("%s", s + 1); dp[0] = 1; for(int i = 1; i <= n; i++) { memset(vis, 0, sizeof(vis)); for(int j = i; j >= 1; j--) { if(vis[s[j] - '0']) break; else { vis[s[j] - '0'] = 1; dp[i] = (dp[i] + dp[j - 1]) % mod; } } } printf("%lld ", dp[n]); return 0; }
C.MRT Map (最短路) 不会写最短路 学姐写的
D.Husam's Bug (水题)
E.Abdalrahman Ali Bugs (水题)
F.Certifications (水题)
G.In the Chairman's office (水题)
H.Give Me This Pizza
题意:给一个数组 求每个数右边第一个比他大的数是谁
题解:ai才不到50 从后往前暴力即可 存每个数最后出现的位置

#include <bits/stdc++.h> using namespace std; int vis[55]; int q[100005]; int ans[100005]; int main() { int n; scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &q[i]); for(int i = 1; i <= 50; i++) vis[i] = 1000005; for(int i = 1; i <= n; i++) ans[i] = 1000005; for(int i = n; i >= 1; i--) { vis[q[i]] = i; int f = -1; for(int j = q[i] + 1; j <= 50; j++) { if(vis[j] < ans[i]) { ans[i] = vis[j]; f = j; } } ans[i] = f; } for(int i = 1; i <= n; i++) { if(i != n) printf("%d ", ans[i]); else printf("%d ", ans[i]); } return 0; }
I.Husam and the Broken Present 1 (水题)
J.Husam and the Broken Present 2 (状压DP) 题解戳
K.Counting Time (模拟)
题意:给一个九宫格的初始状态 填完这个九宫格使得每个数字x能跳到x+1的方案有多少种
能跳到的区域为八连通 且x只能跳到x+1
题解:模拟

#include <bits/stdc++.h> using namespace std; int nx[10]; int ny[10]; int vis[10]; char tu[5][5]; int dx[10]; int dy[10]; int q[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int ans; bool check() { dx[q[1]] = dx[q[2]] = dx[q[3]] = 1; dx[q[4]] = dx[q[5]] = dx[q[6]] = 2; dx[q[7]] = dx[q[8]] = dx[q[9]] = 3; dy[q[1]] = dy[q[4]] = dy[q[7]] = 1; dy[q[2]] = dy[q[5]] = dy[q[8]] = 2; dy[q[3]] = dy[q[6]] = dy[q[9]] = 3; for(int i = 1; i <= 9; i++) if(vis[i]) { if(dx[i] == nx[i] && dy[i] == ny[i]) continue; else return false; } for(int i = 2; i <= 9; i++) { if(abs(dx[i] - dx[i - 1]) <= 1 && abs(dy[i] - dy[i - 1]) <= 1) continue; else return false; } return true; } int main() { ans = 0; for(int i = 1; i <= 3; i++) scanf("%s", tu[i] + 1); for(int i = 1; i <= 3; i++) for(int j = 1; j <= 3; j++) { if(tu[i][j]!= '0') { int c = tu[i][j] - '0'; vis[c] = 1; nx[c] = i; ny[c] = j; } } ans += check(); while(next_permutation(q + 1, q + 10)) ans += check(); printf("%d ", ans); return 0; }