https://vjudge.net/contest/412612#problem/A
求有多少个S子串满足长度是M*L,子串划分为M节长度为L的小子串,M节小子串的每一位都不同
解:哈希然后尺取
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e5 + 5; ll mod = 998244353; ull base[N], h[N]; ull gethash(ll l, ll r) { return h[r] - h[l - 1] * base[r - l + 1]; } int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); ll n, m; ll seed = 31; base[0] = 1; for (int i = 1; i < N; i++) { base[i] = base[i - 1] * 31; } string s; while (cin >> n >> m >> s) { for (int i = 0; i < s.size(); i++) { h[i] = h[i - 1] * seed + s[i]; } ll ans = 0; for (int i = 0; i<m && i+n*m < s.size(); i++) { map<ull,ll> mp; for (int j = i,k = 0; k < n; j += m,k++) { mp[gethash(j, j + m - 1)]++; } if (mp.size() == n) ans++; for (int j = 0; j < (s.size() - n * m - i)/m; j++) { ll tmp = gethash(i + j * m, i + j * m + m - 1); mp[tmp]--; if (mp[tmp] == 0) mp.erase(tmp); mp[gethash(i + j * m + n * m, i + j * m + m - 1 + m * n)]++; if (mp.size() == n) ans++; } } cout << ans << endl; } return 0; }
https://vjudge.net/contest/412612#problem/B
有n个试题,每个题目分值是ai,正确率为0.5,设得分为x,p为最终得分不超过x的概率,求得分ans,满足:P(X<=ans)=p。
解:dp一哈,f_{ij}代表前i个题目得分j的概率
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e5 + 5; ll mod = 998244353; double eps = 1e-4; ll a[50]; int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); ll T; cin >> T; while (T--) { ll n; double p; ll sum = 0; cin >> n >> p; rep(i, 1, n) { cin >> a[i]; sum += a[i]; } vector<vector<double>>f(n+1,vector<double>(sum + 1)); f[0][0] = 1; rep(i, 1, n) { rep(j, 0, sum) { f[i][j] += f[i - 1][j] * 0.5; if(j>=a[i]) f[i][j] += f[i - 1][j - a[i]] * 0.5; } } double ans = 0; rep(i, 0, sum) { ans += f[n][i]; if (ans >= p) { cout << i << endl; break; } } } return 0; }
https://vjudge.net/contest/412612#problem/C
水题
https://vjudge.net/contest/412612#problem/D
n个数字,求从k(1~n),n中选择k个数异或,然后把所有的情况加起来就是答案。
解:拆位,组合数
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e5 + 5; ll mod = 1e6+3; ll c[1005][1005], a[1005]; int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); c[0][0] = 1; rep(i, 1, 1000) { c[i][0] = 1; rep(j, 1, i) { c[i][j] = (c[i - 1][j] + c[i-1][j - 1]) % mod; } } ll n; while (cin >> n) { rep(i, 1, n) { cin >> a[i]; } vector<ll> cnt(35); rep(i, 0, 31) { rep(j, 1, n) { cnt[i] += (a[j] >> i) & 1; } } rep(k, 1, n) { ll ans = 0; rep(i, 0, 31) { for (int j = 1; j <= k; j += 2) { ans = (ans + (c[cnt[i]][j] * c[n - cnt[i]][k - j]) % mod * (1 << i) % mod) % mod; } } cout << ans; if(k!=n) cout<<' '; } cout << endl; } return 0; }
https://vjudge.net/contest/412612#problem/E
思维
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e5 + 5; int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); ll r, y, b; while (cin >> r >> y >> b) { ll le = 0, ri = 0; ll res = 0; if (r > 0) le++, r--; if (y > 0) res += le, le++, y--; if (b > 0) res += le, le++, b--; if (r > 0) ri++, r--, res += le; if (y > 0) res += le + ri, ri++, y--; if (b > 0) res += le + ri, ri++, b--; res += (r + y + b) * (le + ri); cout << res << endl; } return 0; }
https://vjudge.net/contest/412612#problem/F
模拟
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e5 + 5; ll a[50][50], b[50][50],h[50][50]; ll n; void rotate() { rep(i, 1, n) { dec(j, n, 1) { h[n-j+1][i] = a[i][j]; } } rep(i, 1, n) { rep(j, 1, n) { a[i][j] = h[i][j]; } } } ll getDiff() { ll res = 0; rep(i, 1, n) { rep(j, 1, n) { if (a[i][j] == b[i][j]) res++; } } return res; } int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); while (cin >> n,n) { rep(i, 1, n) { rep(j, 1, n) { cin >> a[i][j]; } } rep(i, 1, n) { rep(j, 1, n) { cin >> b[i][j]; } } ll ans = getDiff(); rep(i, 1, 3) { rotate(); ans = max(ans, getDiff()); } cout << ans << endl; } return 0; }
https://vjudge.net/contest/412612#problem/G
旅行商问题,bfs求距离后暴力
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e5 + 5; ll n, m; char g[105][105]; ll dis[6][105][105]; ll finalDis[10][10]; map<pll, ll> mp; ll d[4][2] = { {-1,0},{0,-1},{1,0},{0,1} }; void bfs(ll x, ll y, ll cur) { queue<pll> q; q.push({ x,y }); dis[cur][x][y] = 0; vector<vector<bool>> vis(n + 1, vector<bool>(m + 1)); vis[x][y] = 1; while (!q.empty()) { pll f = q.front(); q.pop(); rep(i, 0, 3) { ll dx = f.first + d[i][0], dy = f.second + d[i][1]; if (dx <= n && dx >= 1 && dy <= m && dy >= 1 && !vis[dx][dy] && g[dx][dy] != '#') { q.push({ dx,dy }); vis[dx][dy] = 1; dis[cur][dx][dy] = dis[cur][f.first][f.second] + 1; } } } for (auto it : mp) { finalDis[cur][it.second] = dis[cur][it.first.first][it.first.second]; } } int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); while (cin >> n >> m, n, m) { ll sx, sy; rep(i, 1, n) { cin >> g[i] + 1; rep(j, 1, m) { if (g[i][j] == '@') sx = i, sy = j; } } mp.clear(); mp[{sx, sy}] = 0; ll k; cin >> k; vector<ll> permutation; rep(i, 1, k) { ll x, y; cin >> x >> y; mp[{x, y}] = i; permutation.push_back(i); } rep(i, 0, k) { rep(j, 0, k) { finalDis[i][j] = INF; } } rep(i, 0, k) { rep(j, 0, n) { rep(p, 0, m) { dis[i][j][p] = INF; } } } for (auto x : mp) { bfs(x.first.first, x.first.second, x.second); } ll ans = INF; do { ll tot = finalDis[0][permutation[0]]; rep(i, 0, k - 2) { tot += finalDis[permutation[i]][permutation[i + 1]]; } ans = min(ans, tot); } while (next_permutation(permutation.begin(), permutation.end())); if (ans == INF) cout << "-1" << endl; else cout << ans << endl; } return 0; }
https://vjudge.net/contest/412612#problem/H
暴力,遍历到中间不合要求的得剪枝,否则过不了。。。
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e5 + 5; ll n, m; char g[205][205]; pll mp[20]; ll cnt; ll d[4][2] = { {-1,1},{1,1},{1,-1},{-1,-1} }; bool check(ll x) { vector<ll> lights; rep(i, 0, cnt - 1) { if ((x>>i) & 1) { lights.push_back(i); } } rep(i,0,(ll)lights.size()-1) { rep(j, 0, 3) { set<pll> st; bool fg = 1; rep(k, 0, lights.size() - 1) { ll x = mp[lights[k]].first, y = mp[lights[k]].second; ll dx = x+d[0][0], dy = y+d[0][1]; if (k == i) { dx = x+d[j][0], dy = y+d[j][1]; } if (g[dx][y] != '#' && g[x][y] != '#' && g[x][dy] != '#') { if (g[dx][y] == '.') st.insert({ dx,y }); if (g[x][y] == '.') st.insert({ x,y }); if(g[x][dy] == '.') st.insert({ x,dy }); } else { fg = 0; break; } } if (st.size() == cnt && fg) { return 1; } } } return 0; } ll getNum(ll x) { ll ans = 0; while (x) { if (x & 1) ans++; x >>= 1; } return ans; } int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif //ios::sync_with_stdio(false); //cin.tie(nullptr); while (cin >> n >> m, n, m) { cnt = 0; rep(i, 0, n + 1) rep(j, 0, m + 1) g[i][j] = ' '; rep(i, 1, n) { scanf("%s",g[i] + 1); rep(j, 1, m) { if (g[i][j] == '.') { mp[cnt++] = { i,j }; } } } ll ans = INF; if (cnt == 0) ans = 0; rep(i, 0, (1<<cnt) - 1) { if (check(i)) { ans = min(ans, getNum(i)); } } if (ans == INF) cout << -1 << '\n'; else cout << ans << '\n'; } return 0; }
https://vjudge.net/contest/412612#problem/I
感觉这个思路比较重要,确定出一张图的上下限,就可以判断是否可以构造出来。如果要去通过构造来说明可以构造的话也太难了而且时间也不允许。
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e5 + 5; ll n, m; struct edge { ll u, v, w; }; vector<edge> e; ll f[N]; ll find(ll x) { return f[x] == x ? x : f[x] = find(f[x]); } void add(ll u, ll v) { ll fu = find(u),fv = find(v); if (fu != fv) f[fu] = fv; } ll getVal() { rep(i, 1, n) { f[i] = i; } ll ans = 0; rep(i, 1, m) { if (find(e[i].u) != find(e[i].v)) { add(e[i].u, e[i].v); ans += e[i].w; } } return ans; } bool check() { ll fa = find(1); rep(i, 2, n) { if (find(i) != fa) return 0; } return 1; } ll fib[50]; int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); fib[1] = 1, fib[2] = 1; rep(i, 3, 45) { fib[i] = fib[i - 1] + fib[i - 2]; } ll T; cin >> T; rep(cas,1,T) { cin >> n >> m; e = vector<edge>(m + 1); rep(i, 1, n) { f[i] = i; } rep(i, 1, m) { cin >> e[i].u >> e[i].v >> e[i].w; add(e[i].u, e[i].v); } cout << "Case #" << cas << ": "; if (check()) { sort(e.begin() + 1, e.end(), [](edge a, edge b) {return a.w < b.w; }); ll down = getVal(); sort(e.begin() + 1, e.end(), [](edge a, edge b) {return a.w > b.w; }); ll up = getVal(); bool fg = 0; rep(i, 1, 45) { if (fib[i] <= up && fib[i] >= down) fg = 1; } if (fg) { cout << "Yes" << endl; } else { cout << "No" << endl; } } else { cout << "No" << endl; } } return 0; }
https://vjudge.net/contest/412612#problem/J
猜的结论,大边和大边组合,贪心
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e5 + 5; double a[20]; int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); ll n; while (cin >> n, n) { rep(i, 1, n) { cin >> a[i]; } double ans = 0; sort(a + 1, a + n+1, [](double u, double v) {return u > v; }); rep(i, 1, n - 2) { if (a[i] < a[i + 1] + a[i + 2]) { double p = (a[i] + a[i + 1] + a[i + 2]) / 2; ans += sqrt(p * (p - a[i]) * (p - a[i+1]) * (p - a[i+2])); i += 2; } } cout << fixed << setprecision(2) << ans << endl; } return 0; }
https://vjudge.net/contest/412612#problem/K
最短路
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e5 + 5; ll n, m; struct node { ll id, w; friend bool operator < (node a,node b) { return a.w > b.w; } }; vector<vector<node>> g; ll dijkstra(ll x) { priority_queue<node> q; vector<ll> dis(n + 1,INF); dis[1] = 0; vector<bool> vis(n + 1); q.push({ 1,0 }); while (!q.empty()) { node f = q.top(); q.pop(); vis[f.id] = 1; for (auto nxt : g[f.id]) { if (nxt.id != x && nxt.w+dis[f.id]<dis[nxt.id]) { dis[nxt.id] = nxt.w + dis[f.id]; if(!vis[nxt.id]) q.push(nxt); } } } return dis[n]; } int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); while (cin >> n >> m,n,m) { ll cnt = 0; g = vector<vector<node>>(n + 1); rep(i, 1, m) { ll u, v, w; cin >> u >> v >> w; g[u].push_back({ v,w }); g[v].push_back({ u,w }); } ll ans = 0; rep(i, 2, n - 1) { ans = max(ans, dijkstra(i)); } if (ans == INF) cout << "Inf" << endl; else cout << ans << endl; } return 0; }
https://vjudge.net/contest/412612#problem/L
区间[1,R-L+1]与区间[L,R]的长度一样,所以如果输出YES,那么区间[L,R]中的数字就是1到R-L+1数字的全排列形式。那么就判断这个满足下面两点就行
1、区间和等于(R-L+2)*(R-L+1)/2;
2.该段区间内没有重复数字。
坑:ll把我T飞了
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e6 + 5; ll n, m; int tr[N << 2], a[N], b[N], sum[N], pos[N]; ll ls(ll x) { return x << 1; } ll rs(ll x) { return x << 1 | 1; } void pushup(ll x) { tr[x] = max(tr[ls(x)] , tr[rs(x)]); } void build(ll p,ll l,ll r) { if (l == r){ tr[p] = b[l]; return; } ll mid = (l + r) >> 1; build(ls(p), l, mid); build(rs(p), mid + 1, r); pushup(p); } ll query(ll ql, ll qr, ll l, ll r, ll p) { if (r < ql || qr < l) return 0; if (ql <= l && r <= qr) return tr[p]; ll mid = (l + r) >> 1; return max(query(ql, qr, l, mid, ls(p)), query(ql, qr, mid + 1, r, rs(p))); } int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); while (cin >> n >> m) { rep(i, 1, n) pos[i] = 0; rep(i, 1, n) { cin >> a[i]; b[i] = pos[a[i]]; pos[a[i]] = i; sum[i] = sum[i - 1] + a[i]; } build(1, 1, n); while (m--) { ll ql, qr; cin >> ql >> qr; ll tmp = qr - ql + 1; if (query(ql, qr, 1, n, 1) < ql && (1 + tmp) * tmp / 2 == sum[qr] - sum[ql-1]) cout<<"YES\n"; else cout<<"NO\n"; } } return 0; }
https://vjudge.net/contest/412612#problem/M
暴力
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define rep(i,a,b) for(ll i=(a);i<=(b);i++) #define dec(i,a,b) for(ll i=(a);i>=(b);i--) #define pll pair<ll,ll> using namespace std; ll INF = 0x7f7f7f7f7f7f7f7f; const int N = 1e6 + 5; ll n; bool mp[220][220]; struct point { ll x, y; friend bool operator < (point a, point b) { if (a.x == b.x) return a.y < b.y; return a.x < b.x; } }p[40]; struct rectangle { point p1, p2; ll area; rectangle(point tp1, point tp2) { p1 = tp1; p2 = tp2; area = (p2.x - p1.x) * (p2.y - p1.y); } rectangle() {}; }r[2000]; ll check(ll i, ll j) { if (r[i].p2.x < r[j].p1.x || r[i].p2.y < r[j].p1.y || r[i].p1.x > r[j].p2.x || r[i].p1.y > r[j].p2.y) { return 1; } if (r[i].p1.x < r[j].p1.x && r[i].p1.y < r[j].p1.y && r[j].p2.x < r[i].p2.x && r[j].p2.y < r[i].p2.y) { return 2; } return 0; } int main() { #ifdef _DEBUG freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(nullptr); while (cin >> n,n) { memset(mp, 0, sizeof mp); rep(i, 1, n) { cin >> p[i].x >> p[i].y; mp[p[i].x][p[i].y] = 1; } sort(p + 1, p + n + 1); ll cnt = 0; rep(i, 1, n) { rep(j, i + 1, n) { if (mp[p[i].x][p[j].y] && mp[p[j].x][p[i].y] && p[j].x > p[i].x && p[j].y>p[i].y) { //r[++cnt].p1 = p[i],r[cnt].p2 = p[j],r[cnt].area = (p[j].y-p[i].y)*(p[j].x - p[i].x); r[++cnt] = rectangle(p[i], p[j]); } } } ll ans = -1; rep(i, 1, cnt) { rep(j, 1, cnt) { if(check(i, j)==1) { ans = max(ans, r[i].area + r[j].area); } else if (check(i, j) == 2) { ans = max(ans, r[i].area); } } } if (ans == -1) cout << "imp" << endl; else cout << ans << endl; } return 0; }