目录
1. P1217 [USACO1.5] 回文质数 Prime Palindromes
题目描述
因为
151
151
151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以
151
151
151 是回文质数。
写一个程序来找出范围
[
a
,
b
]
(
5
≤
a
<
b
≤
100
,
000
,
000
)
[a,b] (5 \le a < b \le 100,000,000)
[a,b](5≤a<b≤100,000,000)(一亿)间的所有回文质数。
输入格式
第一行输入两个正整数 a a a 和 b b b。
输出格式
输出一个回文质数的列表,一行一个。
输入输出样例 #1
输入 #1
5 500
输出 #1
5
7
11
101
131
151
181
191
313
353
373
383
代码
#include <iostream>
#include <vector>
using namespace std;
int a, b;
bool is_prime(int num)
{
for (int i = 2; i <= num / i; i ++)
if (num % i == 0) return false;
return true;
}
bool is_recycle(int num)
{
int sum = 0, cnum = num;
while (num)
{
sum = sum * 10 + num % 10;
num /= 10;
}
if (sum == cnum) return true;
return false;
}
int main()
{
cin >> a >> b;
// 5-100000000(10^8)之间回文素数最大不超过10000000(10^7),然后就能进行一个简单的判断
if (b > 1e7) b = 1e7;
vector<int> recycle;
for (int i = a; i <= b; i ++)
if (is_recycle(i)) recycle.push_back(i);
for (auto r : recycle)
if (is_prime(r)) cout << r << endl;
return 0;
}
2. P3392 涂条纹
题目描述
只要一个由 N × M N \times M N×M 个小方块组成的旗帜符合如下规则,就是合法的图案。
- 从最上方若干行(至少一行)的格子全部是白色的;
- 接下来若干行(至少一行)的格子全部是蓝色的;
- 剩下的行(至少一行)全部是红色的;
现有一个棋盘状的布,分成了
N
N
N 行
M
M
M 列的格子,每个格子是白色蓝色红色之一,小 a 希望把这个布改成合法图案,方法是在一些格子上涂颜料,盖住之前的颜色。
小 A 很懒,希望涂最少的格子,使这块布成为一个合法的图案。
输入格式
第一行是两个整数
N
,
M
N,M
N,M。
接下来
N
N
N 行是一个矩阵,矩阵的每一个小方块是 W(白),B(蓝),R(红)中的一个。
输出格式
一个整数,表示至少需要涂多少块。
输入输出样例 #1
输入 #1
4 5
WRWRW
BWRWB
WRWRW
RWBWR
输出 #1
11
样例解释
目标状态是:
WWWWW
BBBBB
RRRRR
RRRRR
一共需要改 11 11 11 个格子。
数据范围
对于 100 % 100\% 100% 的数据, N , M ≤ 50 N,M \leq 50 N,M≤50。
代码
#include <iostream>
using namespace std;
const int N = 55, INF = 0x3f3f3f3f;
int w[N], b[N], r[N];
char g[N][N];
int n, m;
int get_num(int i, char ch)
{
int num = 0;
for (int j = 1; j <= m; j ++)
if (g[i][j] != ch)
num ++;
return num;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
cin >> g[i][j];
// w[i]:前i行需要全涂成W的格子个数
// b[i]:前i行需要全涂成B的格子个数
// r[i]:前i行需要全涂成R的格子个数
for (int i = 1; i <= n; i ++)
{
w[i] = w[i - 1] + get_num(i, 'W');
b[i] = b[i - 1] + get_num(i, 'B');
r[i] = r[i - 1] + get_num(i, 'R');
// cout << w[i] << ' ' << b[i] << ' ' << r[i] << endl;
}
// 假如说[1, i]为W,[i + 1, j]为B,[j + 1, n]为R
// 则,答案是w[i] + b[j] - b[i] + r[n] - r[j]最小
int res = INF;
for (int i = 1; i <= n - 2; i ++)
for (int j = i + 1; j <= n - 1; j ++)
res = min(res, w[i] + b[j] - b[i] + r[n] - r[j]);
cout << res << endl;
return 0;
}
3. P1149 [NOIP 2008 提高组] 火柴棒等式
题目描述
给你 n n n 根火柴棍,你可以拼出多少个形如 A + B = C A+B=C A+B=C 的等式?等式中的 A A A、 B B B、 C C C 是用火柴棍拼出的整数(若该数非零,则最高位不能是 0 0 0)。用火柴棍拼数字 0 ∼ 9 0\sim9 0∼9 的拼法如图所示:

注意:
- 加号与等号各自需要两根火柴棍;
- 如果 A ≠ B A\neq B A=B,则 A + B = C A+B=C A+B=C 与 B + A = C B+A=C B+A=C 视为不同的等式( A , B , C ≥ 0 A,B,C\geq0 A,B,C≥0);
- n n n 根火柴棍必须全部用上。
输入格式
一个整数 n ( 1 ≤ n ≤ 24 ) n(1 \leq n\leq 24) n(1≤n≤24)。
输出格式
一个整数,能拼成的不同等式的数目。
输入输出样例 #1
输入 #1
14
输出 #1
2
输入输出样例 #2
输入 #2
18
输出 #2
9
说明/提示
【输入输出样例 1 解释】
2 2 2 个等式为 0 + 1 = 1 0+1=1 0+1=1 和 1 + 0 = 1 1+0=1 1+0=1。
【输入输出样例 2 解释】
9 9 9 个等式为
0 + 4 = 4 0+4=4 0+4=4、 0 + 11 = 11 0+11=11 0+11=11、 1 + 10 = 11 1+10=11 1+10=11、 2 + 2 = 4 2+2=4 2+2=4、 2 + 7 = 9 2+7=9 2+7=9、 4 + 0 = 4 4+0=4 4+0=4、 7 + 2 = 9 7+2=9 7+2=9、 10 + 1 = 11 10+1=11 10+1=11、 11 + 0 = 11 11+0=11 11+0=11。
代码
#include <iostream>
#include <vector>
using namespace std;
const int N = 15;
int sticks[10] = {
6, 2, 5, 5, 4,
5, 6, 3, 7, 6
};
int n, cnt;
int trans(int a)
{
// 不加if,肯定bbq
if (a == 0) return sticks[0];
int sum = 0;
while (a)
{
sum += sticks[a % 10];
a /= 10;
}
return sum;
}
int main()
{
cin >> n;
n -= 4;
// 枚举数字a + b = c
// 为什么枚举a,b是1000呢
// 因为题目中n=24,771+0=771满足题意
for (int i = 0; i <= 1000; i ++)
for (int j = 0; j <= 1000; j ++)
{
// 找到数字对应的火柴数num1 num2 num3
int num1 = trans(i), num2 = trans(j),num3 = trans(i + j);
if (num1 + num2 + num3 == n)
{
// cout << i << ' ' << j << ' ' << i + j << endl;
//cout << num1 << ' ' << num2 << ' ' << num3 << endl;
cnt ++;
}
}
cout << cnt << endl;
return 0;
}

586

被折叠的 条评论
为什么被折叠?



