目录
【对整数的每一位进行枚举】
对于整数 a ,对 a 做如下操作,进行每一位的枚举:
while(a!=0){ m=a%10; //m即为从右到左,a的每一位 a/=10;}
对应题目:特别数的和
【对棋盘(二维数组)九宫格位置的枚举】
很多题目都会需要求一个元素周围九宫格的各个元素(如下图所示):
我们可以把中间的元素设置为(0,0),那么它周围8个元素就可以表示出他们的相对位置,就可以得到下面的位置矩阵:
int matrix[9][2]={ {-1,-1}, {-1,0}, {-1,1}, {0,-1}, {0,0}, //为中间的元素 {0,1}, {1,-1}, {1,0}, {1,1} };
根据相对位置矩阵,就可以根据中间元素来判断出其他8个元素的实际位置。
对应题目:图像模糊
【有理数的枚举——Cantor表】
现代数学的著名证明之一是 Georg Cantor 证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的:
1/1 1/2 1/3 1/4 1/5 … 2/1 2/2 2/3 2/4 … 3/1 3/2 3/3 … 4/1 4/2 … 5/1 … …
我们以 Z 字形给上表的每一项编号。第一项是 1/1,然后是 1/2,2/1,3/1,2/2,⋯
输入描述
输入 1 个整数 N, 。
输出描述
输出 表中的第 N 项。
【题解】
可以观察出来每一条线上的有理数都在递增,且每次递增1,可以设置一个累加和 S。
S 的作用是确定 N 的范围,即确定 N 所在哪一条线上,设置这条线上有理数个数为 delt。
可以根据 S 与 N 的差值,确定 N 的位置。
具体代码如下:
#include <iostream> using namespace std; int main() { int s=0; int delt=0; int N; cin>>N; while(s<N){ delt++; s+=delt; } int i=s-N; if(delt%2==0){ cout<<delt-i<<"/"<<1+i; } else { cout<<1+i<<"/"<<delt-i; } return 0; }
【连号区间数】
在 1 ~ N 的某个全排列中有多少个连号区间呢?
这里所说的连号区间的定义是:
如果区间 [L,R] 里的所有元素(即此排列的第 L 个到第 R 个元素)递增排序后能得到一个长度为 R−L+1 的"连续"数列,则称这个区间连号区间。
【对连号区间的判断】
根据连号区间的定义,我们能够得到结论:
该区间的 max - min = 该区间的元素个数 。
于是,我们可以利用双指针来解决此类问题。
具体代码如下:
#include <iostream> using namespace std; #define M 500001 int main() { int N; cin>>N; int arr[M]; for(int i=1;i<=N;i++) cin>>arr[i]; int count_num=0; for(int i=1;i<=N;i++){ int max=0,min=N; for(int j=i;j<=N;j++){ max=arr[j]>max?arr[j]:max; min=arr[j]<min?arr[j]:min; if(max-min==j-i) count_num++; } } cout<<count_num; return 0; }
【最大公约数和最小公倍数】
【最大公约数】
【辗转相除法】——直接上代码啦
int gcd(int x,int y){ int min_num=min(x,y); int max_num=max(x,y); if(max_num%min_num==0) return min_num; return gcd(max_num%min_num,min_num); }
【最小公倍数】
最小公倍数 = x * y / 最大公约数
【日期格式转换问题】
【闰年的判断】
闰年可以被400整除,可以被4整除但是不能被100整除:
bool j_ruen(int a){ if(a%400==0||(a%100!=0&&a%4==0)) return true; else return false; }
【日期的输入和输出格式】
有的题目要求日期的输入格式为:(xx/xx/xx),此时可以用scanf();输出格式要求为: "yyyy−MM−dd",可以用printf()。
但是,在用 scanf()和 printf()的时候,需要加上以下头文件:
#include <cstdio> #define _CRT_SECURE_NO_WARNINGS scanf("%d/%d/%d",&a,&b,&c); printf("%d-%02d-%02d",year,month,date); //02的意思是如果输出的整型数不足两位,左侧用0补齐
更多的枚举题目可以参考如下文章:
本篇文章是对链接中文章的补充,更多关于枚举题目的巧妙方法可以参考链接中文章。