A 合法密码(暴力)
答案
400
kfdhtshmrw4nxg#f44ehlbn33ccto#mwfn2waebry#3qd1ubwyhcyuavuajb#vyecsycuzsmwp31ipzah#catatja3kagbcss2th
对着pdf看了好久qwq
点个赞吧xdm
代码
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
bool isValid(const string& s) {
int num = 0, sym = 0;
for (char c : s) {
if (isdigit(c)) num += 1;
if (!isalnum(c)) sym += 1;
}
return num > 0 && sym > 0;
}
int main() {
string s = "kfdhtshmrw4nxg#f44ehlbn33ccto#mwfn2waebry#3qd1ubwyhcyuavuajb#vyecsycuzsmwp31ipzah#catatja3kagbcss2th";
int n = s.size();
int res = 0;
for (int len = 8; len <= 16; ++len) {
for (int i = 0; i <= n - len; ++i) {
string sub = s.substr(i, len);
if (isValid(sub)) {
res += 1;
}
}
}
cout << res << endl;
return 0;
}
B 选数概率(暴力)
这里先把比值模拟出来再暴力就可以了
因为底都是相同的;
a
×
b
=
2585
a \times b = 2585
a×b=2585
b
×
c
=
2632
b \times c = 2632
b×c=2632
a
×
c
=
1540
a \times c = 1540
a×c=1540
我们通过两式相除法来简化问题并求出 (a)、(b)、(c) 的比值。
我们有以下三个方程:
a × b = 2585 a \times b = 2585 a×b=2585
b × c = 2632 b \times c = 2632 b×c=2632
a × c = 1540 a \times c = 1540 a×c=1540
通过相除来求比值:
首先,将第一个方程和第三个方程相除:
a × b a × c = 2585 1540 \frac{a \times b}{a \times c} = \frac{2585}{1540} a×ca×b=15402585
可以简化为:
b c = 2585 1540 \frac{b}{c} = \frac{2585}{1540} cb=15402585
接下来,将第二个方程和第三个方程相除:
b × c a × c = 2632 1540 \frac{b \times c}{a \times c} = \frac{2632}{1540} a×cb×c=15402632
可以简化为:
b a = 2632 1540 \frac{b}{a} = \frac{2632}{1540} ab=15402632
最后,将第一个方程和第二个方程相除:
a × b b × c = 2585 2632 \frac{a \times b}{b \times c} = \frac{2585}{2632} b×ca×b=26322585
可以简化为:
a c = 2585 2632 \frac{a}{c} = \frac{2585}{2632} ca=26322585
现在,我们得到三个比值:
b c = 2585 1540 , b a = 2632 1540 , a c = 2585 2632 \frac{b}{c} = \frac{2585}{1540}, \quad \frac{b}{a} = \frac{2632}{1540}, \quad \frac{a}{c} = \frac{2585}{2632} cb=15402585,ab=15402632,ca=26322585
我们可以将它们转换成 (a)、(b)、(c) 的比值:
首先,计算 (b : c):
b : c = 2585 1540 b : c = \frac{2585}{1540} b:c=15402585
然后,计算 (b : a):
b : a = 2632 1540 b : a = \frac{2632}{1540} b:a=15402632
最后,计算 (a : c):
a : c = 2585 2632 a : c = \frac{2585}{2632} a:c=26322585
选择 (a_1) 为 1,那么:
a : b : c = 1 : 2632 1540 : 2632 2585 a : b : c = 1 : \frac{2632}{1540} : \frac{2632}{2585} a:b:c=1:15402632:25852632
将其化简:
a : b : c = 3980900 : 6803720 : 4053280 a : b : c = 3980900 : 6803720 : 4053280 a:b:c=3980900:6803720:4053280
gcd( 3980900,gcd(4053280,6803720) )
化简 可知 式子同除72380
最后,得到 (a : b : c) 的比值为:
a : b : c = 55 : 94 : 56 a : b : c = 55 : 94 : 56 a:b:c=55:94:56
已经是互质的,所以答案就是这个。
55,94,56
C 蚂蚁开会
输入一
4
0 0 4 4
0 4 4 0
2 0 0 4
2 1 2 3
输出
2
通过端点求出直线
这里使用gcd
通过模拟一下可以发现 0 0 到 4 4 的 x,y 距离就是 4 4
gcd(4, 4) = 4
然后每次跳的偏移量就是 4 / 4 = 1,4 / 4 = 1
也就是0 0 4 4 这条直线可以穿过 0 0 ,1 1 ,2 2,3 3 ,4 4 这几个点。
每次只枚举整数点
把经过的点存入map
最后遍历map得出答案
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 510, M = 10010;
struct line{
PII p1, p2;
}s[N];
int n, num;
map<PII, int> cnt;
PII points[N * M];
void get_points(line l)
{
int x1 = l.p1.first, y1 = l.p1.second;
int x2 = l.p2.first, y2 = l.p2.second;
int dx = x2 - x1, dy = y2 - y1;
int d = __gcd(abs(dx), abs(dy));
dx /= d, dy /= d;
for (int i = 0;; ++i)
{
int x = x1 + i * dx, y = y1 + i * dy;
points[++num] = {x, y};
if (x == x2 && y == y2) break;
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> s[i].p1.first >> s[i].p1.second;
cin >> s[i].p2.first >> s[i].p2.second;
}
for (int i = 1; i <= n; ++i)
{
get_points(s[i]);
}
int ans = 0;
for (int i = 1; i <= num; ++i)
{
cnt[points[i]]++;
if (cnt[points[i]] == 2)
ans++;
}
cout << ans << endl;
return 0;
}
考场上当时是暴力模拟的
D 立定跳远
应该是二分,但是稍微有点复杂
#include "bits/stdc++.h"
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
auto check = [&](int x) {
int need = 0;
for (int i = 1; i <= n; i++) {
need += max(0, (a[i] - a[i - 1] + x - 1) / x - 1);
}
return need <= m + 1;
};
int l = 1, r = 1E8, ans = 0;
while (l <= r) {
int m0 = (l + r) >> 1;
if (check(m0)) {
r = m0 - 1;
ans = m0;
} else {
l = m0 + 1;
}
}
cout << ans << '\n';
return 0;
}
借鉴的知乎大佬的
E 最小字符串 (暴力)
第一组
4 3
abbc
cba
输出
aabbbcc
第二组
7 3
lanqiao
bei
输出
beilanqiao
这题直接贪心
签到题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
int main()
{
ios :: sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
string s, p;
cin >> s >> p;
sort(p.begin(), p.end());
int i = 0, j = 0;
while(i < n && j < m)
{
if(s[i] > p[j])
{
cout << p[j++];
}
else if(s[i] == p[j])
{
cout << s[i++];
cout << p[j++];
}
else
{
cout << s[i++];
}
}
while(i < n)
{
cout << s[i++];
}
while(j < m)
{
cout << p[j++];
}
return 0;
}
F 数位翻转
输入一
5 3
11 12 13 14 15
输出
67
输入二
6 2
23 8 11 19 16 35
输出
134
这题感觉正解就是暴力
我感觉也不会TLE
首先模拟翻转之后会增加的ai
然后打上标记
记录翻转后的值
最后做一个区间合并再排序就行了
构造的特例如下
5 1
11 11 15 11 11
处理后的数组为
13 13 15 13 13
这里就是把整个数组整体处理一遍
所以打标记的时候需要将相等的也打上!!!!
最后做一个区间合并就行了
细节比较多,不好拿分。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1010;
int n, m;
LL a[N], w[N];
bool st[N];
bool cmp(int a, int b)
{
return a > b;
}
LL get_val(LL x)
{
LL res = 0;
while (x)
{
res = (res << 1) | (x & 1);
x >>= 1;
}
return res;
}
int main()
{
cin >> n >> m;
LL sum = 0;
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
sum += a[i];
}
for (int i = 1; i <= n; ++i) w[i] = get_val(a[i]);
// for(int i = 1; i <= n; ++i) cout << w[i] << " ";
for(int i = 1;i <= n;i ++ )
{
if(w[i] >= a[i]) st[i] = true;
}
int res = 0;
vector<int> ans;
for(int i = 1;i <= n;i ++)
{
if(st[i] && !st[i + 1])
{
res += w[i] - a[i];
ans.push_back(res);
res = 0;
}
else if(st[i] && st[i + 1])
{
res += w[i] - a[i];
}
}
sort(ans.begin(), ans.end(),cmp);
for(int i = 0;i < m && i < ans.size();i ++)
{
sum += ans[i];
}
cout << sum << endl;
return 0;
}
但是这其实是一种贪心的策略,不保证一定是对的
下面的dp写法应该才是真正的正解
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
vector<int> in;
int fan(int x)
{
int ans=0;
for(;x;x>>=1)
{
ans=((ans<<1)|(x&1));
}
return ans;
}
void read()
{
cin>>n>>m;
in=vector<int>(n+1);
for(int i=1;i<=n;i++)
{
cin>>in[i];
}
}
int solve()
{
const int inf=1e16;
vector<vector<int>> dp(2,vector<int>(2*m+1,-inf));
int now=1,old=0;
dp[now][0]=0;
for(int w=1;w<=n;w++)
{
swap(now,old);
dp[now]=vector<int>(2*m+1,-inf);
for(int sta=0;sta<=2*m;sta++)
{
dp[now][sta]=max(dp[old][sta],sta?dp[old][sta-1]:-inf)+((sta&1)?fan(in[w]):in[w]);
}
}
int ans=0;
for(int sta=0;sta<=2*m;sta++)
{
ans=max(ans,dp[now][sta]);
}
return ans;
}
signed main()
{
read();
cout<<solve();
}
亲亲们点个赞呗
G 数星星
输入一
6
1 2
1 3
2 4
2 5
3 6
3 4
输出
6
统计每个点的度数,然后组合数一下。
#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int n, deg[N];
int l, r;
LL fac[N], inv[N], ans[N];
LL qmi(LL a, LL b, LL p)
{
LL res = 1;
while (b)
{
if (b & 1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
void init()
{
fac[0] = inv[0] = 1;
for (int i = 1; i <= n; ++i)
{
fac[i] = fac[i - 1] * i % mod;
}
for (int i = 1; i <= n; ++i)
{
inv[i] = qmi(fac[i], mod - 2, mod);
}
}
LL C(int n, int m)
{
return fac[n] * inv[m] % mod * inv[n - m] % mod;
}
int main()
{
cin >> n;
init();
for (int i = 1; i < n; ++i)
{
int a, b;
cin >> a >> b;
++deg[a], ++deg[b];
}
cin >> l >> r;
ans[1] = n, ans[2] = n - 1;
for (int i = 1; i <= n; ++i)
{
if (deg[i] >= 2)
{
for (int j = 3; j <= deg[i] + 1; ++j)
{
ans[j] = (ans[j] + C(deg[i], j - 1)) % mod;
}
}
}
LL sum = 0;
for (int i = l; i <= r; ++i)
sum = (sum + ans[i]) % mod;
cout << sum << endl;
return 0;
}
H 套手镯
8 12 9
18 22 1
3 17 2
21 28 1
7 18 2
10 2 2
4 24 2
19 13 1
14 15 1
输出
3
#include "bits/stdc++.h"
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, w, h;
cin >> n >> w >> h;
vector<int> x(n), y(n), r(n);
for (int i = 0; i < n; i++) {
cin >> x[i] >> y[i] >> r[i];
}
int ans = 0;
auto work = [&](int x0, int y0, int h, int w) {
int x1 = x0 + h, y1 = y0 + w;
int res = 0;
for (int i = 0; i < n; i++) {
if (x[i] - r[i] >= x0 && x[i] + r[i] <= x1) {
if (y[i] - r[i] >= y0 && y[i] + r[i] <= y1) {
res++;
}
}
}
ans = max(ans, res);
};
for (int i = 0; i < n; i++) {
work(x[i] - r[i], y[i] - r[i], h, w);
work(x[i] - r[i], y[i] - r[i], w, h);
work(x[i] + r[i] - h, y[i] + r[i] - w, h, w);
work(x[i] + r[i] - w, y[i] + r[i] - h, w, h);
work(x[i] - r[i], y[i] + r[i] - h, w, h);
work(x[i] - r[i], y[i] + r[i] - w, h, w);
work(x[i] + r[i] - h, y[i] - r[i], h, w);
work(x[i] + r[i] - w, y[i] - r[i], w, h);
}
cout << ans << '\n';
return 0;
}
这个也是借鉴的
I 跳石头
输入
5
4 3 5 2 1
输出
4
这题是暴力,算了一下可能会超时
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1000010;
int a[N];
int n;
void dfs(int u,set<int> &s)
{
if(u > n) return;
if( u * 2 <= n)
{
s.insert(a[u * 2]);
dfs(u * 2,s);
}
if(u + a[u] <= n)
{
s.insert(a[u + a[u]]);
dfs(u + a[u],s);
}
return;
}
int main()
{
ios :: sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for(int i = 1;i <= n;i ++)
{
cin >> a[i];
}
int maxv = -1;
for(int i = 1;i <= n;i ++)
{
set<int> s;
s.insert(a[i]);
dfs(i,s);
maxv = max(maxv,(int)s.size());
}
cout << maxv << endl;
return 0;
}
还有一种写法是拓扑排序
#include <bits/stdc++.h>
using namespace std;
const int N = 40010;
bitset<N> st[N];
int n, c[N], deg[N];
vector<int> e[N];
void bfs()
{
queue<int> q;
for (int i = 1; i <= n; ++i)
if (!deg[i]) q.push(i);
while (q.size())
{
int u = q.front();
q.pop();
for (int i = 0; i < e[u].size(); ++i)
{
int v = e[u][i];
st[v] |= st[u];
if (--deg[v] == 0) q.push(v);
}
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> c[i];
st[i][c[i]] = 1;
if (i * 2 <= n)
{
++deg[i];
e[i * 2].push_back(i);
}
if (i + c[i] <= n)
{
++deg[i];
e[i + c[i]].push_back(i);
}
}
bfs();
int ans = 0;
for (int i = 1; i <= n; ++i)
{
int m = st[i].count();
ans = max(ans, m);
}
cout << ans << endl;
return 0;
}
J 最长回文前后缀
输入
abcdebijbba
输出
3
听说是kmp
但是暴力也不是不能写对吧😋
总结
由于目前还没有测试网站,所以代码并不保证一定能ac只是提供一个思路给大家,大家喜欢的可以点点关注