枚举
例题:
-
求二位数的个位,十位
#include <iostream> using namespace std; /* *两位数的年龄,比儿子大27岁,年龄俩数字交换位置刚好是儿子的年龄。 */ int main() { int tot = 0; for (int i = 10;i <=99; ++i) { if( i - (i % 10 * 10 + i / 10) == 27) { cout << "爸爸我:" << i << ",儿子:" << i - 27 << endl; tot++; } } cout << tot << endl; return 0; } /* 爸爸我:30,儿子:3 爸爸我:41,儿子:14 爸爸我:52,儿子:25 爸爸我:63,儿子:36 爸爸我:74,儿子:47 爸爸我:85,儿子:58 爸爸我:96,儿子:69 7 */
-
求质数
#include <iostream> using namespace std; int main() { int n, m; cin >> n >> m; //解决n和m的大小关系问题 if (n > m) { swap(n, m); } for (int j = n; j <= m; j++) { if (j == 1) { continue; //1既不是质数,也不是合数 } bool is_prime = true; for (int i = 2; i * i <= j; i++) { //一个数分解成两数之积时,最起码得有一个数小于等于自身开根号 if (j % i == 0) { is_prime = false; break; } } if (is_prime) { cout << j << "\tPRIME" << endl; } } return 0; } /* 10 1 2 PRIME 3 PRIME 5 PRIME 7 PRIME */
-
随机数
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
/*
随机生成长度为10的只含大写字母的字符串
让电脑自行枚举,找到生成的字符
*/
int main()
{
srand(time(NULL));
char s[10];
for (int i = 0; i < 10; i++)
{
s[i] = (char)(65 + rand() % 26);
printf("%c", s[i]);
}
printf("\n");
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 26; j++)
{
if (s[i] == (char)(65 + j))
{ //这里时间复杂度O(10 * 26),而不是26的十次方
//因为26的10次方表示字符串的每一位都枚举完,然后比对
//而实际上,每一遍枚举26个确定一个字符,总共十遍,也就是26乘10
cout << (char)(65 + j);
break;
}
}
}
}
-
回文,各位之和
#include <iostream> #include <cstdio> using namespace std; /* 从5位或6位的十进制数字中找出各个数位之和等于n的回文数字 */ int n; int digit[6]; bool judge(int x) { int m = 0, sum = 0; while (x) { digit[m++] = x % 10; sum += x % 10; x /= 10; } if (sum != n) { //各位数之和是否等于n return false; } for (int i = 0; i < m / 2; i++) { //是否是回文数字 if (digit[i] != digit[m - 1 - i]) { return false; } } return true; } int main() { bool f = false; cin >> n; for (int i = 10000; i < 1000000; i++) { if (judge(i)) { cout << i << endl; f = true; } } if (!f) { cout << -1 << endl; } } /* 48 699996 789987 798897 879978 888888 897798 969969 978879 987789 996699 */
-
四叶玫瑰数
#include <iostream> #include <cmath> using namespace std; bool rose(int i) { int a = i / 1000, b = i / 100 % 10, c = i / 10 % 10, d = i % 10; int ans = a * a * a * a + b * b * b * b + c * c * c * c + d * d * d * d; //不用pow(),因为小数次方运算方法比较奇怪,double类型在算比较大的数时不准 if(ans == i) { return true; } return false; } int main() { int n; cin >> n; if (n < 1000 || n > 9999) { cout << "error!" << endl; } else { for (int i = 1000; i <= n; i++) { if (rose(i)) { cout << i << endl; } } } } /* 输入: 9999 输出: 1634 8208 9474 */
-
循环条件要注意思考
#include <iostream> using namespace std; /* *从某人x岁开始,每到生日就吹等于年龄的数量的蜡烛,如今吹了总共236个蜡烛,问是从几岁开始的,假设人的年龄小于200 */ int main() { for (int i = 1; i <= 200; i++) { int can = 0, j = i; while (can < 236 && j <= 200) { can += j; j++; } if (can == 236) { cout << i << endl; // 26 } } }
-
检验数字中是否含有某一位等于4
#include <iostream> using namespace std; /* *从n到m(都是5位数)里有多少个没有4的数字 */ bool judge(int x) { //判断是否有4,有则返回true while (x) { if (x % 10 == 4) { return true; } x /= 10; } return false; } int main() { int n, m, cnt = 0; cin >> n >> m; for (int i = n; i <= m ; i++) { if (!judge(i)) { cnt++; } } cout << cnt << endl; return 0; } /* 输入: 10000 99999 输出: 52488 */
-
想要判断一个数是不是整数,可以强制转换为整数,看看两者之间有没有差。
#include <iostream> using namespace std; /* *求a^2 + b^2 + c^2 = n 的所有解 *0 < a < b < c *结果按照a的值从小到大输出 */ int main() { int n; cin >> n; for (int a = 1; a * a<= n; a++) { for (int b = a + 1; a * a + b * b <= n; b++) { for (int c = b + 1; a * a + b * b + c * c <= n; c++) { if (a * a + b * b + c * c == n) { cout << a << " " << b << " " << c << endl; } } } } return 0; } /* 输入: 1000 输出: 6 8 30 10 18 24 */
-
遍历矩阵,要找到上下左右四个边界
#include <iostream> using namespace std; /* n*m矩阵,求非空子阵(要求行和列连续),使得子矩阵中元素和最大 */ int A[55][55]; int main() { int n, m, ans; cin >> n >> m; ans = -105; //避免选空矩阵 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> A[i][j]; } } for (int i = 0; i < n; i++) { //上边界 for (int j = i; j < n; j++) { //下边界 for (int k = 0; k < m; k++) { //左边界 for (int l = k; l < m; l++) { //有边界 int tmp = 0; for (int p = i; p <= j; p++) { for (int q = k; q <= l; q++) { tmp += A[p][q]; } } if (tmp > ans) { ans = tmp; } } } } } cout << ans << endl; return 0; } /* 输入: 3 3 2 - 4 1 - 1 2 1 4 - 2 2 输出: 6 */
-
n个数,裁剪一段要求该段的数值之和最大;如果所有的数都小于0,则放弃,最终为0。 1 ≤ n ≤ 1000 1 \leq n \leq 1000 1≤n≤1000。
输入:
5
-1 2 -1 2 -1
输出:
3
动态规划,时间复杂度O(n)。
枚举起点,再枚举终点,再求和,是 O ( n 3 ) O(n^3) O(n3)
枚举起点,往后走,一路记录这个和,看谁最大,是 O ( n 2 ) O (n^2) O(n2)
枚举左右端点,再拿前面的和 O ( 1 ) O(1) O(1) 计算子段和,是 O ( n 2 ) O(n^2) O(n2)
//O(n^2) #include <iostream> using namespace std; int a[1005]; int main() { int n, sum = 0, ans = 0; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0; i < n; i++) { //枚举起点 sum = 0; for (int j = i; j < n; j++) { sum += a[j]; if (sum > ans) { ans = sum; } } } cout << ans << endl; return 0; } /* 输入: 5 -1 2 -1 2 -1 输出: 3 */
-
取差的绝对值,可以简单的if else
#include <iostream> using namespace std; /* n个整数,找到差最小的两个数,求差的最小值 2 <= n <= 100; 1 <= Li <= 10000 差是没有负值的 */ int L[105]; int main() { int n, ans = 10005; //差最大就是10000-1=9999,设一个比这个大的即可 cin >> n; for (int i = 0; i < n; i++) { cin >> L[i]; } for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (L[i] >= L[j]) { if (L[i] - L[j] < ans) { ans = L[i] - L[j]; } } else { if (L[j] - L[i] < ans) { ans = L[j] - L[i]; } } } } cout << ans << endl; return 0; } /* 输入: 5 3 4 1 6 8 输出: 1 */