This commit is contained in:
HuangHai
2025-08-30 18:35:01 +08:00
commit 1f397eca87
6258 changed files with 1487241 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
#include <bits/stdc++.h>
using namespace std;
int cnt;
/*
110
10
*/
int main() {
int n;
cin >> n;
for (int i = 100; i <= n; i++)
if (i % 10 != 3 && i % 100 / 10 != 5 && i % 1000 / 100 != 7)
cnt++;
printf("%d\n", cnt);
return 0;
}

View File

@@ -0,0 +1,70 @@
/* HDU1427 速算24点 */
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
using namespace std;
const int N = 4;
int a[N];
bool flag;
bool dfs(int cnt, int result1, int result2) {
if (cnt == N - 1) {
if (result1 + result2 == 24 || result1 - result2 == 24 || result1 * result2 == 24)
flag = true;
if (result2 != 0 && result1 % result2 == 0 && result1 / result2 == 24)
flag = true;
} else if (!flag) {
// 先算前2项
dfs(cnt + 1, result1 + result2, a[cnt + 1]);
dfs(cnt + 1, result1 - result2, a[cnt + 1]);
dfs(cnt + 1, result1 * result2, a[cnt + 1]);
if (result2 != 0 && result1 % result2 == 0)
dfs(cnt + 1, result1 / result2, a[cnt + 1]);
// 先算后2项,相当与后2项计算是加括号的
dfs(cnt + 1, result1, result2 + a[cnt + 1]);
dfs(cnt + 1, result1, result2 - a[cnt + 1]);
dfs(cnt + 1, result1, result2 * a[cnt + 1]);
if (a[cnt + 1] != 0 && result2 % a[cnt + 1] == 0)
dfs(cnt + 1, result1, result2 / a[cnt + 1]);
}
return false;
}
int main() {
for (;;) {
char s[4];
for (int i = 0; i < N; i++) {
if (scanf("%s", s) == EOF)
return 0;
if (strlen(s) == 2)
a[i] = 10;
else if (s[0] == 'A')
a[i] = 1;
else if (s[0] == 'J')
a[i] = 11;
else if (s[0] == 'Q')
a[i] = 12;
else if (s[0] == 'K')
a[i] = 13;
else
a[i] = s[0] - '0';
}
sort(a, a + N);
flag = false;
do {
dfs(1, a[0], a[1]);
if (flag)
break;
} while (next_permutation(a, a + N));
printf("%s\n", flag ? "Yes" : "No");
}
return 0;
}

View File

@@ -0,0 +1,18 @@
#include <bits/stdc++.h>
using namespace std;
string str = "cacd";
// 3
int bucket[26];
int cnt;
int main() {
//桶计数
for (int i = 0; i < str.size(); i++) bucket[str[i] - 'a']++;
for (int i = 0; i < 26; i++)
if (bucket[i]) cnt++;
cout << cnt << endl;
// t.size()!=cnt
return 0;
}

View File

@@ -0,0 +1,32 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 26;
unordered_set<char> S;
bool st[N];
string res;
string s;
void dfs(int u, string t) {
if (u == s.size()) { //走完全程
if (t.size() == S.size()) { //是不是本路径取得的是最小字串的字符串长度,比如是不是4
if (res == "") //如果是第一次
res = t; // t就成为大王
else if (t < res) //否则t需要击败现在的大王res
res = t;
}
return;
}
if (!st[s[u] - 'a']) { //如果当前字符没有在本路径中出现过,则可以尝试用上当前的字符
st[s[u] - 'a'] = true; //标识已用过
dfs(u + 1, t + s[u]); //下一个位置
st[s[u] - 'a'] = false; //回溯
}
dfs(u + 1, t); //放弃当前位置
}
int main() {
cin >> s;
for (int i = 0; i < s.size(); i++) S.insert(s[i]); //去重后的最小子串长度为S.size()
dfs(0, "");
cout << res << endl;
return 0;
}

View File

@@ -0,0 +1,45 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 26;
// acdaccdd
unordered_set<char> S; //有哪些字符
bool st[N]; //是不是使过了
string res; //结果,字典序最小
string s; //原始串
string t;
void dfs(int u) {
//出口
if (u == s.size()) {
if (t.size() == S.size())
if (t < res) res = t; // t<res
return;
}
//没有使过
if (!st[s[u] - 'a']) {
//使上
st[s[u] - 'a'] = true;
t.push_back(s[u]);
//下一个
dfs(u + 1);
//回溯
t.pop_back();
st[s[u] - 'a'] = false;
}
//使过或者没使过但不想使,都走这条路径
dfs(u + 1);
}
int main() {
//初始化极大值
for (int i = 0; i < 200; i++) res = res + 'z';
//读入字符串
cin >> s;
//去重形成一个集合
for (int i = 0; i < s.size(); i++) S.insert(s[i]);
//深搜
dfs(0);
//输出
cout << res << endl;
return 0;
}

View File

@@ -0,0 +1,35 @@
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 110;
int a[N][N];
int n, m;
// dfs解法
/*
2 3
1 3 5
2 4 6
答案:
13
*/
int dfs(int x, int y) {
if (x == n && y == m) return a[n][m];
if (x + 1 <= n && y + 1 <= m) return a[x][y] + min(dfs(x + 1, y), dfs(x, y + 1));
if (x + 1 <= n && y + 1 > m) return a[x][y] + dfs(x + 1, y);
if (x + 1 > n && y + 1 <= m) return a[x][y] + dfs(x, y + 1);
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
printf("%d\n", dfs(1, 1));
return 0;
}

View File

@@ -0,0 +1,36 @@
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 110;
int a[N][N];
int n, m;
int f[N][N];
// dfs解法
/*
2 3
1 3 5
2 4 6
答案:
13
*/
int dfs(int x, int y) {
if (f[x][y]) return f[x][y];
if (x > n || y > m) return INF;
if (x == n && y == m) return a[n][m];
return f[x][y] = a[x][y] + min(dfs(x + 1, y), dfs(x, y + 1));
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
printf("%d\n", dfs(1, 1));
return 0;
}

View File

@@ -0,0 +1,46 @@
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 110;
int a[N][N];
int n, m;
int res = INF;
// dfs解法
/*
2 3
1 3 5
2 4 6
答案:
13
2 3
1 2 3
4 5 6
*/
int dx[] = {1, 0};
int dy[] = {0, 1};
void dfs(int x, int y, int sum) {
if (x == n && y == m) {
res = min(res, sum);
return;
}
for (int i = 0; i < 2; i++) {
int tx = x + dx[i], ty = y + dy[i];
if (tx > n || ty > m) continue;
dfs(tx, ty, sum + a[tx][ty]);
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
dfs(1, 1, a[1][1]);
printf("%d\n", res);
return 0;
}

View File

@@ -0,0 +1,39 @@
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 110;
int a[N][N];
int n, m;
int res = INF;
void dfs(int x, int y, int sum) {
if (x == n && y == m) {
res = min(res, sum);
return;
}
if (x + 1 <= n)
dfs(x + 1, y, sum + a[x + 1][y]);
if (y + 1 <= m)
dfs(x, y + 1, sum + a[x][y + 1]);
}
/*
2 3
1 3 5
2 4 6
13
*/
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
dfs(1, 1, a[1][1]);
printf("%d\n", res);
return 0;
}

View File

@@ -0,0 +1,39 @@
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 110;
int n, m;
int a[N][N];
int res = INF;
int f[N][N];
/*
动态规划
2 3
1 3 5
2 4 6
答案:
13
*/
int main() {
memset(f, 0x3f, sizeof f);
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
if (i == 1 && j == 1)
f[i][j] = a[i][j];
else
f[i][j] = min(f[i - 1][j], f[i][j - 1]) + a[i][j];
}
printf("%d\n", f[n][m]);
return 0;
}

View File

@@ -0,0 +1,39 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
int f[N][N];
char a[N], b[N];
int al, bl;
/*
测试用例:
abcd
ebde
答案:3
*/
int dfs(int i, int j) {
if (i == 0) return j;
if (j == 0) return i;
if (~f[i][j]) return f[i][j];
//增加、删除
f[i][j] = min(dfs(i - 1, j) + 1, dfs(i, j - 1) + 1);
//修改
if (a[i] == b[j])
return f[i][j] = min(f[i][j], dfs(i - 1, j - 1));
else
return f[i][j] = min(f[i][j], dfs(i - 1, j - 1) + 1);
}
int main() {
memset(f, -1, sizeof f);
cin >> a + 1 >> b + 1;
al = strlen(a + 1), bl = strlen(b + 1);
printf("%d\n", dfs(al, bl));
return 0;
}

View File

@@ -0,0 +1,32 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
char a[N], b[N];
int al, bl;
int f[N][N];
int main() {
cin >> a + 1 >> b + 1;
al = strlen(a + 1), bl = strlen(b + 1);
//初始化
for (int i = 1; i <= bl; i++) f[0][i] = i;
for (int i = 1; i <= al; i++) f[i][0] = i;
for (int i = 1; i <= al; i++)
for (int j = 1; j <= bl; j++) {
//增加删除
f[i][j] = min(f[i - 1][j] + 1, f[i][j - 1] + 1);
//修改
if (a[i] == b[j])
f[i][j] = min(f[i][j], f[i - 1][j - 1]);
else
f[i][j] = min(f[i][j], f[i - 1][j - 1] + 1);
}
printf("%d\n", f[al][bl]);
return 0;
}

View File

@@ -0,0 +1,29 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
int f[N][N], al, bl;
char a[N], b[N];
int main() {
cin >> a + 1 >> b + 1;
al = strlen(a + 1), bl = strlen(b + 1);
for (int i = 1; i <= bl; i++) f[0][i] = i;
for (int i = 1; i <= al; i++) f[i][0] = i;
for (int i = 1; i <= al; i++)
for (int j = 1; j <= bl; j++) {
f[i][j] = min(f[i - 1][j] + 1, f[i][j - 1] + 1);
if (a[i] == b[j])
f[i][j] = min(f[i][j], f[i - 1][j - 1]);
else
f[i][j] = min(f[i][j], f[i - 1][j - 1] + 1);
}
printf("%d\n", f[al][bl]);
return 0;
}

View File

@@ -0,0 +1,145 @@
### 一、题目大意
昨日,糖豆做了一道小学四年级数学举一反三试题:
$\large ~~~~abcdef$
$\large + abcdef$
$\large ----$
$\large ~~~jeghba$
已知题目中所有字符是非负整数,求$abcdef$和$jeghba$的值是多少?
此题我给出的数学方法是画树形图,标注分支,然后尝试每个分支,判断是否符合题目,是否可以剪枝,但计算量很大,糖豆历时$20$分钟,完成此题。
回头思考,既然都画了树形图,不如使用编程的办法尝试一下,随即做了两套办法,现整理给同学们参考,望大家深入理解深搜的优势,以及它的实现细节。
### 二、循环暴力法
$Running~time:1000ms$
$1$秒内完成计算,无法优化了,没法剪枝。贵在思路简单,好上手。
```c++
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
int a[N], al; //用于将最终的两个原数字相加的结果 拆分到数组中
int b[N], bl; //用于拆分原数字到数组中
int main() {
//记录开始时间
clock_t begin = clock();
// 1234
//排重后数字个数
unordered_set<int> _set1, _set2;
for (int i = 123456; i < 1000000 / 2; i++) {
int x = i;
int y = i + i;
al = 0;
while (y) a[++al] = y % 10, y /= 10;
bl = 0;
while (x) b[++bl] = x % 10, x /= 10;
_set1.clear();
for (int j = 1; j <= al; j++) _set1.insert(a[j]);
if (_set1.size() != 6) continue;
_set2.clear();
for (int j = 1; j <= bl; j++) _set2.insert(b[j]);
if (_set2.size() != 6) continue;
if (a[1] == b[6] && a[2] == b[5] && a[5] == b[2]
&& !_set2.count(a[3]) && !_set2.count(a[4]) && !_set2.count(a[6]))
printf("%d\n", i);
}
//记录结束时间
clock_t end = clock();
cout << "Running time:" << (double)(end - begin) / CLOCKS_PER_SEC * 1000 << "ms" << endl;
return 0;
}
```
### 三、深搜+剪枝
$Running~~ time:3ms$
逆天的$3ms$!整整快了$300$倍~
<font color='red' size=4><b>分析:
因深搜可以在行进过程中随时发现问题,随时终止此分支前进,防止了很多无用的枚举。
</b></font>
```c++
#include <bits/stdc++.h>
using namespace std;
/*
输出:
468532
*/
const int N = 10;
int num; //不断增加的前缀,最终是选择的数字
bool st[N]; // 0~9哪个数字使用过
int a[N], al; //用于将最终的两个原数字相加的结果 拆分到数组中
int b[N], bl; //用于拆分原数字到数组中
void dfs(int u) {
if (u == 7) { //完成所有数位的枚举
int sum = num << 1, tmp = num;
//拆分到数组中
al = 0;
while (sum) a[++al] = sum % 10, sum /= 10;
bl = 0;
while (tmp) b[++bl] = tmp % 10, tmp /= 10;
//判断条件,能剪枝的代码,尽量提前,减少后面无用的计算
// 放在unordered_set前面,可以做到: Running time:3ms
if (a[1] != b[6] || a[2] != b[5] || a[5] != b[2]) return;
if (st[a[6]] || st[a[4]] || st[a[3]]) return;
// Running time:526ms
//判断是不是结果存在数位值重复
unordered_set<int> _set;
for (int i = 1; i <= al; i++) _set.insert(a[i]);
if (_set.size() < 6) return;
//全部符合要求,输出结果
printf("%d\n", num);
return;
}
for (int i = 0; i <= 9; i++) {
//首位不能达到5,否则就是7位了,剪枝
//如果是首位,a!=1,因为加法的结果个数是1,加法结果最小应该是2开始
// a只能是2,4
if (u == 1 && (i != 2 && i != 4)) continue;
if (!st[i]) {
st[i] = true;
num = num * 10 + i; //增加上此位
dfs(u + 1); //下一个位置
// num = (num - i) / 10; //减回去此位
//简写
num = num / 10; //减回去此位
st[i] = false;
}
}
}
int main() {
//记录开始时间
clock_t begin = clock();
dfs(1);
//记录结束时间
clock_t end = clock();
cout << "Running time:" << (double)(end - begin) / CLOCKS_PER_SEC * 1000 << "ms" << endl;
return 0;
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB