- 普通题型知识
- 边界值问题
- 反转数字问题
- 反转数字升级版(回文问题)
- 保留小数问题
- 时间及进制问题
- 不足补位、取整问题
- 闰年判断 及 年份月份问题 及 时间未来问题
- 题目逼你输出程序要求的顺序问题
- 求分差问题
- 数学知识
- 正弦 最小正弦值 约分 最大公约数 最小公倍数
- 三角形
- 杨辉三角
- 质数
- 质因数分解
- 奇数偶数
- 排序知识
- sort排序问题
- 枚举暴力模拟知识
- 解题思路
- a=!a
- while里套if 和 套while的区别
- 字符串知识
- 字符串进制问题(Excel地址)
- 关于string
- 字符转换大小写
- 字符转数字 数字转字符
- 数字对应字符
- 递归知识
- 斐波那契数列
- 计算阶层
- 2的n次方
做题必须考虑边界值
1.值为0;
2.值相等;
3.正常算术式算出来整数需要加*1.0才能变为double
反转数字升级版(回文问题)反转数字问题
如果直接用取个位十位百位的方法的题目,会输出0
方法1:如果是固定了几位数,直接输入字符,反着输出字符cin>>a>>b>>c>>d>>e; cout<方法2:用字符串(就是比char强!)string,获取长度,从后往前for循环输出
string a; cin>>a; int b = a.length(); for(int i=b-1;i>=0;i--){ cout<方法三:还得看我stl库 STL里面的反转字符串函数reverse()
string a; cin>>a; reverse(a.begin(),a.end());
保留小数问题如何判断数字反转过来是不是长得还是一样 例如:151 101 313 383
除了11,如果数的位数加起来是偶数就不可能是回文数
这里涉及到一个可以背的模板int ishw(int n){ int nn=n,y=0; while(nn){ y+=nn%10; if(y==n)return 1; y*=10; nn/=10; } return 0; }
时间及进制问题保留小数,c++和c都有不同的方法
c++:cout<
c:printf("%.3lf");
不足补位、取整问题例如24小时算时间
方法1:会出现分钟小-分钟大的问题 这个时候退位,不然小时和分钟都会出问题if(d方法2:将时间统一转换为分钟
ans=(c-a)*60+(d-b); x=ans/60;//小时 y=ans%60;//分钟
cout<
printf("%03d", n);//其中3表示宽度,0表示前面添充0。
向上取整 ceil()
向下取整 floor()
闰年判断
if(n%400==0 || (n%4==0&&n%100!=0)){//能整除400 || 能整除4但不能整除100
cout<<1;
return 0;
}
判断+几天 是某年某日?
这里需要几个知识
1.月份问题
int mouths[]={0,31,28,31,30,31,30,31,31,30,31,30,31};//注意数组第一个为0
之后特判,如果是闰年 mouths[2]=29 否则 mouths[2]=28
2.闰年判断版本
int rn(int n){
if((n%4==0&&n%100!=0) || (n%400==0)){
return 366;
}
return 365;
}
3.解题
cin>>year>>mouth>>day>>n;//题目给的时间,n是题目给的加n天是几月几日
while(n>0){//当n没被用完
if(rn(year)==366)mouths[2]=29;
else mouths[2]=28;//因为闰年改变2月份时间
n--;
day++;//随着n的减少,时间++
if(day>mouths[mouth]){//当day大于本月天数,说明要月份++,天数归为本月第一天
day=1;
mouth++;
if(mouth>12){//月份大于12,年份++,月份归为本年第一月
mouth=1;
year++;
}
}
}
cout<
求有多少个星期几
这里需要几个知识,跟上面差不多
1.月份问题
2.闰年判断版本
3.解题
year=2000,mouth=12,day=31;//题目给的初始天数
int i=1,ans=0;//记录天数 星期答案
while(!(year==1901&&mouth==1&&day==1)){//题目给的结束天数,当没到这个天数,继续减
if(rn(year)==366)mouths[2]=29;
else mouths[2]=28;//同上
day--;
i++;//为了判断到8天则是过了一个星期了
if(i==8){
i=1;
ans++;
}
if(day==0){//同上一题
day=mouths[mouth];
mouth--;
if(mouth==0){
mouth=12;
year--;
}
}
}
cout<
题目逼你输出程序要求的顺序问题
给输出来个for循环和 if
求分差问题
搞个函数
bool check(int a,int b,int c)
{
return a<=b+c && b<=a+c;
}
数学知识
正弦 最小正弦值 约分 最大公约数 最小公倍数
正弦值=直角边/斜边!!!
且最小正弦值=最短直角边/斜边!!!!!
约分:这个数数除以他们的最大公约数就是约分
最小公倍数等于 两数相乘除以最大公约数
那么有人就问了,最大公约数怎么求
1.__gcd //c++自带函数
2.辗转相除法:
int gcd(int x,int y)
{
int r=x%y;
while(r!=0)
{
x=y;
y=r;
r=x%y;//最大公约数,就是题目所说的约分---
}
return y;//返回 最大公约数
}
三角形
如果最长的一条边大于等于另外两条边的长度和,则无法构成三角形
在一个三角形中,如果较短的两条边的平方和大于最长边的平方,那么这个三角形是锐角三角形,否则它是钝角三角形。
一个三角形如果是等边三角形,则必是等腰三角形
但等腰三角形不一定是等边三角形
杨辉三角
除了第一个数和最后一个数是1 其余的等于上方的数 加上 上方左边的数
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
质数
求质数:
int isprime(int n){
if(n<2)return 0;
for(int i=2;i*i
质因数分解
首先要知道唯一分解定理:一个数能且只能分解为一组质数的乘积。可知,若输入的数满足题目条件,他就只能分解为两个质数的乘积。所以在比他小且大于1的自然数中,只有那两个数能整除它,之间不可能再有任何合数或质数能整除它了,因为最小的能整除它的合数已经是他本身了。
记得如果i*j=n;那么求出来i,if(n%i==0)那么n/i就是j
奇数偶数
0是偶数
排序知识
sort排序问题
正常的升序
int main(){
int a[4]={5,4,88,1};
sort(a,a+4);
for(int i=0;i<=3;i++){
cout<
正常的降序
bool cmp(int a,int b){
return a>b;
}
int main(){
int a[4]={5,4,88,1};
sort(a,a+4,cmp);
for(int i=0;i<=3;i++){
cout<
枚举暴力模拟知识
解题思路
1.建立变量记录数组下标(求数所在下标位置)
2.建立变量记录答案变成数组下标++;
a=!a
如果a非0,则变成0;
如果a是0,则变成1
while里套if 和 套while的区别
while里套if,if完成后从while内的第一个语句开始
while里套while,将会一直循环到内while失效
详情见洛谷p5731 蛇形方阵
字符串知识
字符串进制问题(Excel地址)
26转10进制
特别考虑当n=26的时候出现的问题aa= n%26要变成aa=(n-1)%26+1;
特别考虑降幂要去余的问题n=n/26要变成n=(n-aa)/26;
#include
#include
#include
#include
#include
using namespace std;
int a[500],sum=1,aa;
string s;
int f(int n){
while(n){
aa=(n-1)%26+1;
a[sum++]=aa;
n=(n-aa)/26;
}
for(int i=sum-1;i>0;i--){
s[i]=a[i]-1+'A';
cout<>n;
f(n);
return 0;
}
关于string
string字符串形,可直接当做数组,可直接输出。
当遇到空格或换行,string的输入就终止了,如果想继续,可以用while(cin>>),多半还是不行就只能用getline(cin,s)
s.append(ss);//将ss字符串插入s字符串后面
s=s.substr(aa,bb);//提取出从aa起的bb个字符
s.insert(a,b)//将b字符插入到a位置前
(int)s.find(a)//输出字符串a在字符串s中第一次出现的位置
字符转换大小写
字符转换大小写 大转小+32 小转大-32(记得用char强转)
字符转数字 数字转字符
字符-‘0’可以获得相应的整数
数字+‘0’可以获得相应的数字字符
数字对应字符
如1对应a,2对应b,3对应c
/ss[i]=(s[i]-'a')%26 -'a'字符转对应字母表中位置,%26防炸
/ss[i]=char( (s[i]-'a')%26+'a') 从位置再+‘a’数字变字符,强制char
string s,ss;
cin>>s;
for(int i....){ss[i]=s[i]-'a'}
递归知识
斐波那契数列
斐波那契普通递归
#include
using namespace std;
int fbnq(int n){
if(n<=2)return 1;
return fbnq(n-1)+fbnq(n-2);
}
int main()
{
int n;
cin>>n;
cout<
斐波那契记忆化递归
#include
#include
using namespace std;
double x[50]; //记忆结果
double f(int n) {
if(n==0) return 0;
if(n==1) return 1;
if(x[n]!=0)
return x[n]; //若已经算出过结果则直接返回
else
return x[n]=f(n-1)+f(n-2);
}
int main() {
int n;
scanf("%d",&n);
printf("%.2lf",f(n));
return 0;
}
计算阶层
int jc(int n){
if(n==1)return 1;
return n*jc(n-1);
}
2的n次方
i< i>>n 的意思是 i/2的n次方
i应当是整数
洛谷例p5461
现有 2 的n次方 * 2的n次方 (n≤10) 名作弊者站成一个正方形方阵等候发落。决定赦免一些。将正方形矩阵均分为 4 个更小的正方形矩阵,每个更小的矩阵的边长是原矩阵的一半。其中左上角那一个矩阵的所有作弊者都将得到赦免,剩下 3 个小矩阵中,每一个矩阵继续分为 4 个更小的矩阵,然后通过同样的方式赦免作弊者……直到矩阵无法再分下去为止。所有没有被赦免的作弊者都将被处罚。
给出 n,请输出每名作弊者的命运,其中 0 代表被赦免,1 代表不被赦免。
输入格式
一个数 n。
输出格式
2 的n次方 * 2的n次方的 01 矩阵,代表每个人是否被赦免。数字之间有一个空格。
输入
3
输出
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 1
0 0 0 0 0 1 0 1
0 0 0 0 1 1 1 1
0 0 0 1 0 0 0 1
0 0 1 1 0 0 1 1
0 1 0 1 0 1 0 1
1 1 1 1 1 1 1 1
运用递归,我们可以惊奇的发现,一直循环题目给的操作,最终会变成一个2*2小矩形,右上角的会被赦免,其他三个会被处罚,只要从最终的矩阵递归上去即可
#include
#include
#include
#include
#include
using namespace std;
int a[1050][1050];
int cal(int x,int y,int n){
if(n==0)a[x][y]=1;
else{
cal(x+(1<>n;
cal(0,0,n);
for(int i=0;i<1<



