HDU 多校联合第一场
1001
开始没读懂题意,蛋疼的英语。。。
题意是先给26个字母,第i位表示把第i个字母翻译成那个字母。然后再给一个串,前边某些是密文,后边某些是明文。让求的是如果后边的某些明文是前边那些密文翻译过来的一部分。那么把后边的明文补全使得串最短。
中文都说的好纠结。。。出题报告说是eKMP,偶暴力蹭过去的。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <ctime> #include <queue> #include <map> #include <sstream> #include <stack> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) x < y ? x : y #define Max(x, y) x < y ? y : x #define E(x) (1 << (x)) const int eps = 1e-6; const int inf = ~0u>>2;; typedef long long LL; using namespace std; const int N = 100010; int pre[N]; char tmp[30], ts[30]; char ss[N]; char T[N], P[N]; /*void Next(char* p, int n) { int i, k = -1; pre[0] = -1; for(i = 1; i < n; ++i) { while(k > -1 && p[k+1] != p[i]) k = pre[k]; if(p[k+1] == p[i]) ++k; k = pre[k]; } } bool KMP(char* T, char* p) { int n = strlen(T), m = strlen(p); Next(p, m); int i, k; k = -1; for(i = 0; i < n; ++i) { while(k > -1 && p[k+1] != T[i]) k = pre[k]; if(p[k+1] == T[i]) ++k; if(k == m - 1) return true; } return false; }*/ bool match(char* T, char* P) { int i = 0, j = 0; while(T[i] != '\0' && P[j] != '\0') if(T[i++] != P[j++]) return false; return true; } int main() { //freopen("data.in", "r", stdin); int t, n, l, i, j, m; char c; scanf("%d", &t); while(t--) { scanf("%s%s", tmp, ss); for(i = 0; i < 26; ++i) { c = tmp[i]; ts[c-'a'] = i+'a'; } n = strlen(ss); l = (n + 1)/2; CL(T, 0); CL(P, 0); for(i = 0; i < l; ++i) { T[i] = ts[ss[i]-'a']; } T[i] = '\0'; for(i = l; i < n; ++i) { for(m = 0, j = i; j < n; ++j) { P[m++] = ss[j]; } P[m] = '\0'; //puts(T); //puts(P); if(match(T, P)) break; T[i] = ts[ss[i]-'a']; T[i+1] = '\0'; } for(j = 0; j < i; ++j) printf("%c", ss[j]); for(j = 0; j < i; ++j) printf("%c", ts[ss[j]-'a']); cout << endl; } return 0; }
1002
dp题,好蛋疼。
f[i+1][j][0] = (f[i+1][j][0] + f[i][j][0] + f[i][j][1]*2) % MOD; f[i+1][j+1][0] = (f[i+1][j+1][0] + f[i][j][0] + f[i][j][1]) % MOD; f[i+1][j][1] = (f[i+1][j][1] + f[i][j][1]) % MOD; f[i+1][j+1][1] = (f[i+1][j+1][1] + f[i][j][1]*2 + f[i][j][0]*2) % MOD; f[i+1][j+2][1] = (f[i+1][j+2][1] + f[i][j][1] + f[i][j][0]) % MOD;
1003
题意:找离当前position最近的蛋糕,如果左右蛋糕距离一样,则选择到position这个点时的方向继续走。。。
方法1 set:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <ctime> #include <queue> #include <map> #include <sstream> #include <stack> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) x < y ? x : y #define Max(x, y) x < y ? y : x #define E(x) (1 << (x)) const int eps = 1e-6; const int inf = ~0u>>2; typedef long long LL; using namespace std; const int N = 100010; set<int> st; int num[N]; int main() { //freopen("data.in", "r", stdin); int t, n, k, cas = 0; int a, b, d; LL ans, p, np, l, r; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &k); st.clear(); st.insert(0); CL(num, 0); p = 0; ans = 0; while(k--) { scanf("%d", &a); if(a == 0) { scanf("%d", &b); num[b]++; st.insert(b); } else { if(num[p]) {num[p]--; continue;} set<int>::iterator it1, it2; it1 = it2 = st.find(p); l = r = -1; if(it1 != st.begin()) l = *--it1; if(++it2 != st.end()) r = *it2; //printf("%lld %lld\n", l, r); if(l == -1 && r == -1) {continue;} if(l == -1) { ans += r - p; d = 1; np = r; num[r]--; } else if(r == -1) { ans += p - l; d = 0; np = l; num[l]--; } else { if(r - p == p - l) { ans += r - p; if(d == 1) {np = r; num[r]--;} else {np = l; num[l]--;} } else if(r - p > p - l) { ans += p - l; np = l; d = 0; num[l]--; } else { ans += r - p; np = r; d = 1; num[r]--; } } st.erase(p); p = np; } } printf("Case %d: ", ++cas); cout << ans << endl; } return 0; }
方法2 线段树:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <ctime> #include <queue> #include <map> #include <sstream> #include <stack> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) x < y ? x : y #define Max(x, y) x < y ? y : x #define E(x) (1 << (x)) const int eps = 1e-6; const int inf = ~0u>>2;; typedef long long LL; using namespace std; const int N = 100020; struct node { int l, r; int col, Max, Min; } tree[N<<2]; void creat(int t, int l, int r) { tree[t].l = l; tree[t].r = r; tree[t].col = 0; tree[t].Max = -inf; tree[t].Min = inf; if(l == r) return ; int mid = MID(l, r); creat(L(t), l, mid); creat(R(t), mid + 1, r); } void updata(int t, int p, int val) { if(tree[t].l == tree[t].r) { tree[t].col += val; if(tree[t].col) {tree[t].Max = tree[t].Min = p;} else {tree[t].Max = -inf; tree[t].Min = inf;} return ; } int mid = MID(tree[t].l, tree[t].r); if(p <= mid) updata(L(t), p, val); else updata(R(t), p, val); tree[t].Max = max(tree[L(t)].Max, tree[R(t)].Max); tree[t].Min = min(tree[L(t)].Min, tree[R(t)].Min); } int get_max(int t, int l, int r) { if(tree[t].l >= l && tree[t].r <= r) { return tree[t].Max; } int mid = MID(tree[t].l, tree[t].r); if(l > mid) return get_max(R(t), l, r); else if(r <= mid) return get_max(L(t), l, r); else { return max(get_max(L(t), l, mid), get_max(R(t), mid + 1, r)); } } int get_min(int t, int l, int r) { if(tree[t].l >= l && tree[t].r <= r) { return tree[t].Min; } int mid = MID(tree[t].l, tree[t].r); if(l > mid) return get_min(R(t), l, r); else if(r <= mid) return get_min(L(t), l, r); else { return min(get_min(L(t), l, mid), get_min(R(t), mid + 1, r)); } } int main() { //freopen("data.in", "r", stdin); int t, n, m, cas = 0;; int p, np, l, r, d, a, b; LL ans; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); p = ans = 0; d = 1; creat(1, 0, n + 1); while(m--) { scanf("%d", &a); if(a == 0) { scanf("%d", &b); updata(1, b, 1); } else { l = get_max(1, 0, p); r = get_min(1, p, n); //printf("%d %d\n", l, r); if(l <= -inf && r >= inf) continue; else if(l <= -inf) { ans += r - p; np = r; d = 1; } else if(r >= inf) { ans += p - l; np = l; d = 0; } else { if(r - p == p - l) { ans += r - p; if(d == 1) np = r; else np = l; } else if(r - p > p - l) { ans += p - l; d = 0; np = l; } else { ans += r - p; d = 1; np = r; } } updata(1, np, -1); p = np; } } printf("Case %d: ", ++cas); cout << ans << endl; } return 0; }
1009
看着就像搜索。。。可以用优先队列。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <ctime> #include <queue> #include <map> #include <sstream> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) x < y ? x : y #define Max(x, y) x < y ? y : x #define E(x) (1 << (x)) const int eps = 1e-6; const int inf = ~0u>>2; typedef long long LL; using namespace std; const int N = 5002; struct node { int x, y, d; node(int a = 0, int b = 0, int c = 0) : x(a), y(b), d(c) {} bool operator < (const node& tmp) const { return d > tmp.d; //优先级要搞清楚 } }; struct pos { int x; int y; pos() {} pos(int a, int b) : x(a), y(b) {} } stk[510]; int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; char mp[N][N]; bool vis[N][N]; int n, m, cost, t; bool inmap(int x, int y) { if(x < 0 || x >= n || y < 0 || y >= m) return false; return true; } int bfs(int x, int y) { CL(vis, 0); priority_queue<node> q; //注意这个要放到函数里,不然会MLE q.push(node(x, y, 0)); int i, j, nx, ny; node u; vis[x][y] = true; while(!q.empty()) { u = q.top(); q.pop(); for(i = 0; i < 4; ++i) { nx = u.x + dir[i][0]; ny = u.y + dir[i][1]; if(!inmap(nx, ny) || vis[nx][ny] || mp[nx][ny] == '#') continue; vis[nx][ny] = true; if(mp[nx][ny] == 'C') return u.d; if(mp[nx][ny] == 'P') { for(j = 0; j < t; ++j) { q.push(node(stk[j].x, stk[j].y, u.d)); } } else if(mp[nx][ny] == '*') { q.push(node(nx, ny, u.d + cost)); } } } return -1; } int main() { //freopen("data.in", "r", stdin); int i, j, x, y, ans; while(~scanf("%d%d%d", &n, &m, &cost)) { for(i = 0; i < n; ++i) { scanf("%s", mp[i]); } t = 0; for(i = 0; i < n; ++i) { for(j = 0; j < m; ++j) { if(mp[i][j] == 'Y') {x = i, y = j;} else if(mp[i][j] == 'P') { stk[t++] = pos(i, j); } } } ans = bfs(x, y); if(ans == -1) puts("Damn teoy!"); else printf("%d\n", ans); } return 0; }