第一天刷算法总结(例子均含详细代码)
1. 注意长整型的使用(遇到数字范围比较大的)细细分析
1.1长整型
图片摘自:https://baike.baidu.com 有符号长整型(long int)有一位去作符号位了,所以大致2的正负31次之间 图片摘自:http://c.biancheng.net/cpp/html/20.html int,short int 两字节,16位,2的16次幂 范围大致到万级别 long 四字节,32位,2的32次幂 范围大致到十亿级别
1.2长整型 整形位数容易误解的点
后来发现一个问题,就是我发现我输入了千万级别的数竟然也能存到int里,不需要long,后来发现是因为 我用的编译器是32位的,而1.1中的级别位数是16位下的位数 我总结为下: 16 位:见1.1 32位 : int 4 字节 32位(long 也是) 2^32级别 十亿级别 64位:long 8字节 64位 比万亿级别还要多好几位 int 4位(同32位情况)
2.完全平方数
2.1 定义
若一个数能表示成某个整数的平方的形式,则称这个数为完全平方数。完全平方数是非负数, 而一个完全平方数的项有两个。
2.2与完全平方式的区别:
完全平方式是代数式,完全平方数是自然数。
2.3 例:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
法一:(借鉴同学)
#include <iostream>
using namespace std;
#include <cmath>
int main() {
int a, b, c, d;
for (int i = 1; i <= 100000; i++) {
a = sqrt(i + 100);
b = sqrt(i + 268);
if (a * a == i + 100 && b * b == i + 268)
cout << i << endl;
}
return 0;
}
法一 将数 i从1至100000进行枚举,通过该数i加100(or 268)开根号的值再平方是否还等于i+100(or 268)来判断是否根号出来的是个整数,若开出来是整数则符合要求,若开出来不是整数但向下取整了,故而后续验证值也不等。 法二: 摘自https://www.runoob.com/cprogramming/c-exercise-example3.html 程序分析:
假设该数为 x。
1、则:x + 100 = n2, x + 100 + 168 = m2
2、计算等式:m2 - n2 = (m + n)(m - n) = 168
3、设置: m + n = i,m - n = j,i * j =168,i 和 j 至少一个是偶数 (偶数乘任意一个数都是偶数,奇数乘奇数是奇数)
4、可得: m = (i + j) / 2, n = (i - j) / 2,i 和 j 要么都是偶数,要么都是奇数。(奇数+奇数=偶数+偶数=偶数,奇数+偶数=奇数)
5、从 3 和 4 推导可知道,i 与 j 均是大于等于 2 的偶数。(完全平方数是非负数)
6、由于 i * j = 168, j>=2,则 1 < i < 168 / 2 + 1。
7、接下来将 i 的所有数字循环计算即可。
#include <stdio.h>
int main (void)
{
int i, j, m, n, x;
for (i = 1; i < 168 / 2 + 1; i++)
{
if (168 % i == 0)
{
j = 168 / i;
if ( i > j && (i + j) % 2 == 0 && (i - j) % 2 == 0)
{
m = (i + j) / 2;
n = (i - j) / 2;
x = n * n - 100;
printf ("%d + 100 = %d * %d\n", x, n, n);
printf ("%d + 268 = %d * %d\n", x, m, m);
}
}
}
return 0;
}
3. 年月日问题(涉及闰年问题,天数问题)
3.1 判断任意年份是否为闰年,需要满足以下条件中的任意一个:
① 该年份能被 4 整除同时不能被 100 整除;(十年一闰百年不闰) ② 该年份能被400整除。(每四百年再一闰)
普通闰年:公历年份是4的倍数且不是100的倍数为普通闰年(如2004、2020年就是闰年)。 世纪闰年:公历年份是整百数的,必须是400的倍数才是世界闰年(如2000是世纪闰年,1900不是世纪闰年)。
例:输入某年某月某日,判断这一天是这一年的第几天?
自写:
#include <iostream>
using namespace std;
int main() {
int arr[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int yea, mon, day, result = 0;
cin >> yea >> mon >> day;
if ((yea % 4 == 0 && yea % 100 != 0) || yea % 400 == 0) {
arr[1] == 29;
}
for (int j = 0; j <= mon - 2; j++) {
result += arr[j];
}
result += day;
cout << result << endl;
return 0;
}
4. c 语言输入输出格式
4.1 scanf有& printf无&
scanf("%d",&a);
printf("%d",a);
4.2一般的c++程序占用内存大于c源程序
图片摘自:https://zhidao.baidu.com/question
5. 有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?(做法比较)
5.1 代码
法一(自写)
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 4; i++)
for (int j = 1; j <= 4; j++) {
if (i == j)
continue;
for (int k = 1; k <= 4; k++) {
if (k == i || k == j)
continue;
cout << i * 100 + j * 10 + k << " " << endl;
}
}
return 0;
}
法二(借鉴同学)
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 4; i++)
for (int j = 1; j <= 4; j++) {
for (int k = 1; k <= 4; k++) {
if (i != j && i != k && j != k)
cout << i << j << k << endl;
}
}
return 0;
}
5.2 做法比较总结
法二的解法就更加暴力些,这种方法是将可填在个位十位百位上的情况全部排列出来(用三层循环),然后把不符合条件的排列去掉(即要求三个数不等),这是一种做题思路,即做其他题时也可考虑先把所有情况考虑出来,再去掉特殊情况(不符合条件的情况)。而且法二的输出不是通过计算出结果输出的是直接按位输出结果的
6.利润奖金例题及做法比较
6.1 例题
企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高 于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提 成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于 40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于 100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数? 程序分析:请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。
6.2 代码
法一(自写)
#include <iostream>
using namespace std;
int main() {
long int profit, reward;
cin >> profit;
if (profit <= 100000) {
reward = profit * 0.1;
} else if (profit > 100000 && profit <= 200000) {
reward = 100000 * 10 % +(profit - 100000) * 0.075;
} else if (profit > 200000 && profit <= 400000) {
reward = 100000 * 0.1 + 100000 * 0.075 + (profit - 200000) * 0.05;
} else if (profit > 400000 && profit <= 600000) {
reward = 100000 * 0.1 + 100000 * 0.075 + 200000 * 0.05 + (profit - 400000) * 0.03;
} else if (profit > 600000 && profit <= 1000000) {
reward = 100000 * 0.1 + 100000 * 0.075 + 200000 * 0.05 + 200000 * 0.03 + (profit - 600000) * 0.015;
} else if (profit > 1000000) {
reward = 100000 * 0.1 + 100000 * 0.075 + 200000 * 0.05 + 200000 * 0.03 + 400000 * 0.015 + (profit - 1000000) * 0.01;
}
cout << reward << endl;
return 0;
}
法二:(借鉴同学)
#include <iostream>
using namespace std;
int god( int a) {
int jj;
if (a <= 100000)
jj = a * 0.1;
else if (a > 100000 && a <= 200000)
jj = god(100000) + (a - 100000) * 0.075;
else if (a > 200000 && a <= 400000)
jj = god(200000) + (a - 200000) * 0.05;
else if (a > 400000 && a <= 600000)
jj = god(400000) + (a - 400000) * 0.03;
else if (a > 600000 && a <= 1000000)
jj = god(600000) + (a - 600000) * 0.015;
else if (a > 1000000)
jj = god(1000000) + (a - 1000000) * 0.01;
return jj;
}
int main() {
int a, jj;
cin >> a;
cout << god(a);
return 0;
}
6.3 做法比较
法二运用了递归的思想,而法一仅仅是按照要求列出来,前面范围的计算部分重复罗列,容易敲错,但是要比递归要快些,这是一种做题思路,当遇到大量重复部分的问题可作为其他问题的子问题时,可考虑用递归解决。
6.4 递归
以下三张图片均摘自:https://baike.baidu.com/item/%E9%80%92%E5%BD%92/1740695
7. 变量命名技巧
8. 例:输入三个整数x,y,z,请把这三个数由小到大输出。
法一:(自写)
#include <iostream>
using namespace std;
int main() {
int x, y, z, min;
cin >> x >> y >> z;
int t;
if (x > y) {
t = y;
y = x;
x = t;
}
if (x > z) {
t = z;
z = x;
x = t;
}
if (y > z) {
t = z;
z = y;
y = t;
}
cout << x << " " << y << " " << z << endl;
return 0;
}
法二: 摘自:https://blog.csdn.net/qq894492015/article/details/78893657
#include<stdio.h>
int min(int a,int b){
return a>b?b:a;
}
int max(int a,int b){
return a>b?a:b;
}
void main()
{
int x,y,z;
scanf("%d,%d,%d",&x,&y,&z);
printf("small to big is %d %d %d\n", min(min(x,y),z), (x>min(min(x,y),z) && x<max(max(x,y),z)) ? x : y>min(min(x,y),z) && y<max(max(x,y),z) ? y : z, max(max(x,y),z));
}
9. 制作九九乘法表
首先得知道长什么样子: 代码:
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
cout << j << "*" << i << "=" << i *j;
printf("\t");
}
cout << endl;
}
return 0;
}
|