题目集1
A
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;
}
B
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;
}
C
https://vjudge.net/contest/412612#problem/C
水题
D
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;
}
E
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;
}
F
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;
}
G
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;
}
H
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;
}
I
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;
}
J
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;
}
K
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;
}
L
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;
}
M
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;
}