B题:
先处理出已有卡牌,然后进行dfs,dfs有个很大的剪枝,就是当前位置如果字典序小于了,那么后面就不用继续放了,直接用组合数学进行计算即可,如果大于就不用考虑了,如果等于才继续往后搜,这样的话,搜等于只要在字典序相等的一条路上搜,时间可以接受
E题:模拟即可,不存在无解情况
G题:先全部数字GCD一遍,如果不为1,就是无解,如果为1,那么构造答案,其实只要拿第一个数字,可以其他每个数字做一次gcd,第一个数字就是1了,然后再拿第一个数字和后面数字做gcd,就全部都是1了,一共进行n - 2次
H题:这题有个大坑啊,字符串居然只要满足是子串就可以了- -,感觉题目说的不是那么清楚,于是只要把已有字符串构造一棵字典树,然后dp[x][y][u],表示当前在x,y这个位置,在字典树中位置为u的状态需要的最小步树,然后进行最短路即可,遇到单词结点的时候,可以记录一下答案的最小值
代码:
B:
#include <cstdio> #include <cstring> typedef long long ll; const int MOD = 1000000007; char str[105]; int st[52], have[14], stn, hn, C[105][105]; int cal(int tot) { int ans = 1; for (int i = 1; i <= 13; i++) { if (have[i]) { ans = (int)((ll)ans * C[tot][have[i]] % MOD); tot -= have[i]; } } return ans; } int dfs(int u) { int ans = 0; if (u == stn) return 0; if (hn - u == 0) return 1; for (int i = 1; i <= st[u]; i++) { if (!have[i]) continue; have[i]--; if (i == st[u]) { ans = (ans + dfs(u + 1)) % MOD; } else if (i < st[u]) { ans = (ans + cal(hn - u - 1)) % MOD; } have[i]++; } return ans; } int main() { for (int i = 0; i < 105; i++) { C[i][0] = C[i][i] = 1; for (int j = 1; j < i; j++) { C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD; } } while (gets(str) != NULL) { stn = 0; hn = 0; int len = strlen(str); memset(have, 0, sizeof(have)); for (int i = 0; i < len; i++) { if (str[i] == 'A') st[stn++] = 1; else if (str[i] == '1') { st[stn++] = 10; i++; } else if (str[i] >= '2' && str[i] <= '9') st[stn++] = str[i] - '2' + 2; else if (str[i] == 'J') st[stn++] = 11; else if (str[i] == 'Q') st[stn++] = 12; else if (str[i] == 'K') st[stn++] = 13; have[st[stn - 1]]++; } for (int i = 1; i <= 13; i++) { have[i] = 4 - have[i]; hn += have[i]; } printf("%d\n", dfs(0)); } return 0; }
E:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 15; const int INF = 0x3f3f3f3f; int t, n, a[N]; void gao() { while (1) { int Min = INF, Max = -INF; int Minv, Maxv; for (int i = 0; i < n; i++) { if (Min > a[i]) { Min = a[i]; Minv = i; } if (Max < a[i]) { Max = a[i]; Maxv = i; } } if (Min == Max) break; a[Minv] = a[Maxv] = Max - Min; } } int main() { scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); gao(); printf("%d\n", a[0]); } return 0; }
G:
#include <cstdio> #include <cstring> const int N = 100005; int gcd(int a, int b) { if (!b) return a; return gcd(b, a % b); } int n, a; int main() { int cas = 0; while (~scanf("%d", &n)) { int s = 0; for (int i = 0; i < n; i++) { scanf("%d", &a); s = gcd(s, a); } printf("Case %d: ", ++cas); if (s != 1) { printf("-1\n"); } else { printf("%d\n", 2 * n - 2); for (int i = 2; i <= n; i++) printf("1 %d\n", i); for (int i = 2; i <= n; i++) printf("1 %d\n", i); } printf("\n"); } return 0; }
H:
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int N = 25; const int MAXN = 20005; const int INF = 0x3f3f3f3f; int t, n, m; char str[N][N], s[105]; int ch[MAXN][26], sz, dp[N][N][MAXN]; bool val[MAXN]; void init() { sz = 0; memset(val, 0, sizeof(val)); memset(ch[0], 0, sizeof(ch[0])); } int idx(char c) { return c - 'A'; } void insert(char *str) { int len = strlen(str); int u = 0; for (int i = 0; i < len; i++) { int c = idx(str[i]); if (!ch[u][c]) { ch[u][c] = ++sz; memset(ch[sz], 0, sizeof(ch[sz])); } u = ch[u][c]; } val[u] = true; } struct State { int x, y, u, val; State() {} State(int x, int y, int u, int val) { this->x = x; this->y = y; this->u = u; this->val = val; } bool operator < (const State& c) const { return val > c.val; } }; const int d[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; int main() { scanf("%d", &t); while (t--) { priority_queue<State> Q; scanf("%d%d", &n, &m); memset(dp, INF, sizeof(dp)); for (int i = 0; i < n; i++) { scanf("%s", str[i]); for (int j = 0; j < m; j++) { if (str[i][j] == '@') { Q.push(State(i, j, 0, 0)); dp[i][j][0] = 0; } } } int q; int ans = INF; scanf("%d", &q); init(); while (q--) { scanf("%s", s); insert(s); } while (!Q.empty()) { State now = Q.top(); Q.pop(); if (val[now.u]) ans = min(ans, now.val); if (now.val >= ans) continue; for (int i = 0; i < 4; i++) { int x = now.x + d[i][0]; int y = now.y + d[i][1]; if (x < 0 || x >= n || y < 0 || y >= m || str[x][y] == '#') continue; if (dp[x][y][0] > now.val + 1) { dp[x][y][0] = now.val + 1; Q.push(State(x, y, 0, now.val + 1)); } if (str[x][y] >= 'A' && str[x][y] <= 'Z') { int u = now.u; int c = idx(str[x][y]); while (1) { u = ch[u][c]; if (u == 0) break; if (dp[x][y][u] > now.val + 1) { dp[x][y][u] = now.val + 1; Q.push(State(x, y, u, now.val + 1)); } } } else { int u = now.u; if (dp[x][y][u] > now.val + 1) { dp[x][y][u] = now.val + 1; Q.push(State(x, y, u, now.val + 1)); } } } } if (ans == INF) ans = -1; printf("%d\n", ans); } return 0; }
时间: 2024-11-25 02:15:32