整数运算
基本的输入输出
#include <iostream>
using namespace std;
int main()
{
int a,b;
scanf("%d,%d",&a,&b);
cout << a << "+" << b << "=" << a + b << endl;
cout << a << "-" << b << "=" << a - b << endl;
return 0;
}
日期
格式化输入即可
#include <iostream>
using namespace std;
int main()
{
int y,m,d;
scanf("%2d/%2d/%4d",&m,&d,&y);
printf("%04d%02d%02d",y,m,d);
return 0;
}
平均分
基本的输入输出
#include <iostream>
using namespace std;
int main( )
{
double a,b,c;
cin >> a >> b >> c;
printf("%lf\n%lf",a + b + c,(a + b + c) / 3.0);
return 0;
}
最大公约数
高中数学:辗转相除法
#include <iostream>
using namespace std;
int gcd(int a,int b)
{
if(a % b == 0)return b;
else return gcd(b,a % b);
}
int main( )
{
int a,b;
cin >> a >> b;
cout << gcd(a,b) << endl;
return 0;
}
整除幸运数
定义一个函数来实现提取某个数每位上的数字,一旦遇到不含7或者4的情况则返回false,代表此数不是幸运数,否则返回true
实现函数
bool judge(int n)
{
while(n > 0)
{
int num = n % 10;
if(num != 4 && num != 7)return false;
n /= 10;
}
return true;
}
eg1:
n = 8484848
第一次循环:n = 8484848,num = 8,不符合情况,返回false
eg2:
n = 4747447
第一次循环:n = 4747447,num = 7,符合情况,执行n /= 10(n /= 10等价于n = n / 10)
第二次循环:n = 474744,num = 4,符合情况,执行n /= 10(n /= 10等价于n = n / 10)
第三次循环:n = 47474,num = 4,符合情况,执行n /= 10(n /= 10等价于n = n / 10)
第四次循环:n = 4747,num = 7,符合情况,执行n /= 10(n /= 10等价于n = n / 10)
第五次循环:n = 474,num = 4,符合情况,执行n /= 10(n /= 10等价于n = n / 10)
第六次循环:n = 47,num = 7,符合情况,执行n /= 10(n /= 10等价于n = n / 10)
第七次循环:n = 4,num = 4,符合情况,执行n /= 10(n /= 10等价于n = n / 10)
第八次循环:由于4 / 10 = 0,n = 0,不满足while循环条件,跳出循环返回true
#include <iostream>
using namespace std;
bool judge(int n)
{
while(n > 0)
{
int num = n % 10;
if(num != 4 && num != 7)return false;
n /= 10;
}
return true;
}
int main()
{
int n;
cin >> n;
int flag = 0;
for(int i = 2;i <= n;i ++ )
{
if(judge(i) && n % i == 0)
{
flag = 1;
break;
}
}
if(flag == 1)cout << "YES";
else cout << "NO";
return 0;
}
线段
本质为前n项和的求取的递推
以下分别为当n = 1、2、3、4时线段的条数
可以发现题目让求解的为(n - 1)的阶乘
int sum(int n)
{
int ans = 0;
for(int i = 0;i <= n;i ++ )ans += i;
return ans;
}
在mian函数重调用即可
#include <iostream>
using namespace std;
int sum(int n)
{
int ans = 0;
for(int i = 0;i <= n;i ++ )ans += i;
return ans;
}
int main()
{
int n;
cin >> n;
cout << sum(n - 1) << endl;
return 0;
}
圆切平面
注意:本题求取的是平面
递推+贪心思维:假设新圆的添加总能完美相交于之前所有圆
一个圆截得的平面数2
两个圆截得的平面数4
三个圆截得的平面数为8
设n - 1个圆最多分割a[n - 1]个平面,在添加第n个圆之后能够完美分割前n -1个圆,于是新增加的平面数即为2 * (n - 1),由递推可得:a[i] = a[i - 1] + 2 * (n - 1)
如果还不清楚的话,请看数学推论
#include <iostream>
using namespace std;
const int N = 1000000 + 10;
int a[N];
int main()
{
int n;
cin >> n;
a[1] = 2;
a[2] = 4;
for(int i = 3;i <= n;i ++ )a[i] = a[i - 1] + 2 * (i - 1);
cout << a[n] << endl;
return 0;
}
数字7
若是7的和或者差,则7必定为其因子,将n对7取余即可,注意特判,0也属于正确答案。例如:7 - 7
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
if(n == 0)
{
cout << "YES";
return 0;
}
if(n < 0)n = abs(n);
if(n % 7 == 0)cout << "YES";
else cout << "NO";
return 0;
}
个人所得税
大模拟、if-else分支结构
#include <iostream>
using namespace std;
int main()
{
int n,ans = 0;
cin >> n;
if(n <= 500)ans = n * 0.05 - 0;
else if(n > 500 && n <= 2000)ans = n * 0.1 - 25;
else if(n > 2000 && n <= 5000)ans = n * 0.15 - 125;
else if(n > 5000 && n <= 20000)ans = n * 0.2 - 375;
else if(n > 20000 && n <= 40000)ans = n * 0.25 - 1375;
else if(n > 40000 && n <= 60000)ans = n * 0.3 - 3375;
else if(n > 60000 && n <= 80000)ans = n * 0.35 - 6375;
else if(n > 80000 && n <= 100000)ans = n * 0.4 - 10375;
else ans = n * 0.45 - 15375;
cout << ans << endl;
return 0;
}
偶数位
十进制与二进制的互相转换
十进制转二进制,定义trans函数
十进制转二进制的本质为:n不断模2取余,倒序链接即可
string trans(int n)
{
string s;
while(n > 0)
{
int num = n % 2;
char c = num + '0';
s += c;
n /= 2;
}
reverse(s.begin(),s.end());
return s;
}
eg:
10
第一次循环:n = 10,num = 0,s += s + '0';s = "0";n /= 2;
第二次循环:n = 5,num = 1,s = s + '1';s = "01";n /= 2;
第三次循环:n = 2,num = 0,s = s + '0';s = "010" ;n /= 2;
第四次循环:n = 1,num = 1,s = s + '1';s = "0101" ;n /= 2;
第五次循环不再执行,因为n == 0跳出
再将s反转得到"1010"即为10的二进制数
替换偶数位为0
void deal(string &s)
{
reverse(s.begin(),s.end());
for(int i = 0;i < s.size();i ++ )
{
if(i % 2 == 0)s[i] = '0';
}
reverse(s.begin(),s.end());
}
由于操作以右端为开头,反转过来操作即可,操作之后再反转返回
十进制转二进制
int getans(string s)
{
reverse(s.begin(),s.end());
int w = 1,ans = 0;
for(int i = 0;i < s.size();i ++ )
{
int num = s[i] - '0';
ans += num * w;
w *= 2;
}
return ans;
}
最右端为第0位,权重为2^0 = 1,其后随着位数的增加权重依次增大,累加即可
int getans(string s)
{
reverse(s.begin(),s.end());
int w = 1,ans = 0;
for(int i = 0;i < s.size();i ++ )
{
int num = s[i] - '0';
ans += num * w;
w *= 2;
}
return ans;
}
在main函数中调用即可
#include <iostream>
#include <algorithm>
using namespace std;
string trans(int n)
{
string s;
while(n > 0)
{
int num = n % 2;
char c = num + '0';
s += c;
n /= 2;
}
reverse(s.begin(),s.end());
return s;
}
void deal(string &s)
{
reverse(s.begin(),s.end());
for(int i = 0;i < s.size();i ++ )
{
if(i % 2 == 0)s[i] = '0';
}
reverse(s.begin(),s.end());
}
int getans(string s)
{
reverse(s.begin(),s.end());
int w = 1,ans = 0;
for(int i = 0;i < s.size();i ++ )
{
int num = s[i] - '0';
ans += num * w;
w *= 2;
}
return ans;
}
int main()
{
int n;
cin >> n;
string s;
s = trans(n);
deal(s);
cout << getans(s);
return 0;
}
合并
对应数乘其权重累加
#include <iostream>
using namespace std;
int main()
{
int a,b,c;
cin >> a >> b >> c;
cout << a * 100 + b * 10 + c << endl;
return 0;
}
公式计算
注意c ++ 默认下取整,且有着即使命名为double s,s = 3 / 2仍不等于1.5的情况出现,避免此类情况将公式中出现的所有整数加个.0后缀即可
#include <iostream>
using namespace std;
int main()
{
int x,a;
cin >> x >> a;
double ans = 0.5 * (a * 1.0 * x * 1.0 + (a + x) * 1.0 / (4 * a * 1.0));
printf("%.2lf",ans);
return 0;
}
进制形式
可以偷个懒使用c语言的格式化输出
%o 八进制 %d 十进制 %x 十六进制
不偷懒的话也可以学学函数实现进制转换
#include <iostream>
using namespace std;
int main()
{
int n = 128;
int m = 456789;
printf("%d %o %x\n",n,n,n);
printf("%d %o %X\n",m,m,m);
return 0;
}
等差数列
首先储存a,b,c,vector为c ++ 类型的动态数组,sort函数默认排序为升序排序
因此将这三个数存入vector后sort即可得到一个可能递增的有序序列(可能a == b || a == c || a == b && a == c && b == c)
由高中数学知识得,等差中项为前一项和后一项的和除以2
为了避免出现c ++ 向下取整的特殊情况,将公式进行等价变形
b = (a + c) / 2 -> 2 * b = a + c
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> A;
int main()
{
for(int i = 1;i <= 3;i ++ )
{
int num;
cin >> num;
A.push_back(num);
}
sort(A.begin(),A.end());
if(A[0] + A[2] == 2 * A[1])cout << "YES";
else cout << "NO";
return 0;
}
网球比赛
无输入,逻辑思考出答案,直接输出即可
#include <iostream>
using namespace std;
int main()
{
cout << "a with z" << endl;
cout << "b with x" << endl;
cout << "c with y" << endl;
return 0;
}
大小写的转换
根据ASCII码转换:ASCII表
小写英文字母的ASCII码比对应的大写英文字母的ASCII码要大32
#include <iostream>
using namespace std;
int main()
{
char c;
cin >> c;
if(c >= 'a' && c <= 'z')c -= 32;
else if(c >= 'A' && c <= 'Z')c += 32;
cout << c << endl;
return 0;
}
宽度与对齐
%m.d输出宽度为m的整数
%d为右对齐,%-d为左对齐,
#include <iostream>
using namespace std;
int main()
{
int a = 455;
int b = -123;
int c = 987654;
printf("%-5d %5d\n",a,a);
printf("%-5d %5d\n",b,b);
printf("%-5d %5d\n",c,c);
return 0;
}
左右对齐
%m.nlf输出宽度为m,精度为n的浮点数
%lf为右对齐,%-lf为左对齐
#include <iostream>
using namespace std;
int main()
{
double a = 3.1415926;
double b = 22.3456;
printf("%-14.6lf %14.6lf\n",a,a);
printf("%-14.6lf %14.6lf\n",b,b);
return 0;
}
输入宽度
格式化读入与格式化输出
#include <iostream>
using namespace std;
int main()
{
int a,b,c;
scanf("%3d%3d%3d",&a,&b,&c);
printf("%d %d %d",a,b,c);
return 0;
}
宽度精度
使用c ++ 实现,#include <iomanip>为其头文件
setiosflags(ios::fixed)为输出固定位数
setprecision(m)为输出精度为m的小数
setw(n)为输出宽度为n的数字
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int n,m;
cin >> n >> m;
double a = 18.16054;
double b = 17.676767;
cout << setw(n) << setiosflags(ios::fixed) << setprecision(m) << a << ' ' << setw(n) << setiosflags(ios::fixed) << setprecision(m) << b << endl;
return 0;
}
四位数逆序
移步至上文《数字7》,同理,换汤不换药
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
while(n > 0)
{
cout << n % 10;
n /= 10;
}
return 0;
}
整理玩具
公式递推:
假设有一个玩具:{1}
假设有两个玩具:{1,1} {2}
假设有三个玩具:{1,1,1} {1,2}
假设有四个玩具:{1,1,1,1} {1,1,2} {2,2}
假设有五个玩具:{1,1,1,1,1} {1,2,2} {1,1,1,2}
对应答案依次为:
当n = 1时,1 + 0 = 1
当n = 2时,1 + 1 = 2
当n = 3时,1 + 1 = 2
当n = 4时,1 + 2 = 3
当n = 5时,1 + 2 = 3
递推可得公式ans = 1 + n / 2
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
cout << 1 + n / 2 << endl;
return 0;
}
字符判断
if - else分支结构
#include <iostream>
using namespace std;
int main()
{
char c;
cin >> c;
if(c >= '0' && c <= '9')cout << "Number" << endl;
else if(c >= 'A' && c <= 'Z')cout << "Capital letter" << endl;
else if(c >= 'a' && c <= 'z')cout << "Lowercase letter" << endl;
else if(c == '+' || c == '-' || c == '*' || c == '/')cout << "Arithmetic operators" << endl;
else if(c == '=' || c == '>' || c == '<')cout << "Relational operators" << endl;
else if(c == '!' || c == '&' || c == '|' || c == '^')cout << "Logical operators" << endl;
else cout << "Other character" << endl;
return 0;
}
单位矩阵
高等数学-线性代数之中的概念,于编程之中可以理解为只有主对角线元素为1,其余元素均为0的二维矩阵
#include <iostream>
using namespace std;
int a[10][10];
int main()
{
for(int i = 1;i <= 3;i ++ )
{
for(int j = 1;j <= 3;j ++ )
{
cin >> a[i][j];
if(i == j)
{
if(a[i][j] == 1)continue;
else
{
cout << "NO";
return 0;
}
}
else if(a[i][j] != 0)
{
cout << "NO";
return 0;
}
}
}
cout << "YES";
return 0;
}
闰年
闰年有两种情况
- 能被4整除且不能被100整除
- 能被400整除
#include <iostream>
using namespace std;
bool judge(int n)
{
if((n % 4 == 0 && n % 100 != 0) || (n % 400 == 0))return true;
else return false;
}
int main()
{
int n;
cin >> n;
if(judge(n))cout << "Y";
else cout << "N";
return 0;
}
时间也能加
只考虑题目要求,首先秒满60进1,其次分钟满60再进1
#include <iostream>
using namespace std;
int main()
{
int h1,m1,s1,h2,m2,s2;
cin >> h1 >> m1 >> s1 >> h2 >> m2 >> s2;
int h = h1 + h2;
int m = m1 + m2;
int s = s1 + s2;
if(s >= 60)
{
m ++ ;
s -= 60;
}
if(m >= 60)
{
h ++ ;
m -= 60;
}
cout << h << " " << m << " " << s;
return 0;
}
非常大的N
#include <cmath>库中的sqrt函数
sqrt(a,b)获取a的b次方
开方使b = 0.5即可,即a的0.5次方,a的开方
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double ans = 0;
int n,flag = 1;
cin >> n;
for(int i = 1;i <= n;i ++ )
{
ans += sqrt(i) * flag;
flag = -flag;
}
printf("%.6lf",ans);
return 0;
}
三角形坐标
根据公式输出计算即可,注意c ++ 向下取整以及double类型整数除整数仍得整数的情况,为整数添加.0后缀
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int x1,y1,x2,y2,x3,y3;
cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
double S = 0.5 * abs(x1 * y2 + x2 * y3 + x3 * y1 - x1 * y3 - x2 * y1 - x3 * y2);
printf("%.2lf",S);
return 0;
}
向下取整
还是#include <cmath>库
sqrt函数(移步至《非常大的N》)和floor函数
floor(a);为对a的向下取整
eg:
floor(3.999999) = 3;
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double n;
cin >> n;
int ans = floor(pow(n,1.0 / 3));
printf("%3d",ans);
return 0;
}
时刻求和
对12取余即可
#include <iostream>
using namespace std;
int main()
{
int a,b;
cin >> a >>b;
printf("%3d",(a + b) % 12);
return 0;
}
点与线段的关系
首先题目当中包含无关的字符,要抑制这些字符的读入只读数字
int x1,y1,x2,y2,x3,y3;
scanf("(%d,%d) (%d,%d)\n",&x1,&y1,&x2,&y2);
scanf("(%d,%d)",&x3,&y3);
其次判断点是否在线段上
- 三点共线公式
(x2-x1) * (y3-y1) - (x3-x1) * (y2-y1) == 0
- 只有点位于线段上才算正确,因此点3到点1的距离与点3到点2的距离是严格小于等于点1到点2距离的
- 计算两点之间的距离
int dis(int x1,int y1,int x2,int y2)
{
int s = pow((x1 - x2),2) + pow((y1 - y2),2);
return s;
}
综上所述
#include <iostream>
#include <cmath>
using namespace std;
int dis(int x1,int y1,int x2,int y2)
{
int s = pow((x1 - x2),2) + pow((y1 - y2),2);
return s;
}
int main()
{
int x1,y1,x2,y2,x3,y3;
scanf("(%d,%d) (%d,%d)\n",&x1,&y1,&x2,&y2);
scanf("(%d,%d)",&x3,&y3);
if((x2-x1) * (y3-y1) - (x3-x1) * (y2-y1) == 0 && dis(x1,y1,x2,y2) >= dis(x1,y1,x3,y3) && dis(x1,y1,x2,y2) >= dis(x2,y2,x3,y3))cout << "YES";
else cout << "NO";
return 0;
}
卡罗尔数
化简4 * n - 2 * (n + 1) - 1 = 2 * n - 3 = N <---> n = (N + 3) / 2
在这里使用一个类型转换的方式
double n;根据输入的N求出n的值,题目要求n必须为正整数,因此浮点数n的小数位不能有数字double flag = n - int(n);来获取标志
eg:
输入N = 1,n = 4 / 2.0 = 2.0;int(n) = 2;double flag = 2.0 - 2 = 0
输入N = 2,n = 5 / 2.0 = 2.5;int(n) = 2;double flag = 2.5 - 2 = 0.5
因此,若是flag为0,则n为正整数,输出YES,否则输出NO
#include <iostream>
using namespace std;
int main()
{
int N;
cin >> N;
double n = (N + 3) / 2.0;
double flag = n - int(n);
if(flag == 0)cout << "YES" << endl;
else cout << "NO" << endl;
return 0;
}
整除的总数
if语句
#include <iostream>
using namespace std;
int main()
{
int n,m,k,ans = 0;
cin >> n >> m >> k;
for(int i = n;i <= m;i ++ )
{
if(i % k == 0)ans ++ ;
}
cout << ans << endl;
return 0;
}
尾数为零
循环,if语句
#include <iostream>
using namespace std;
typedef long long ll;
ll fun(ll n)
{
ll ans = 1;
for(ll i = 1;i <= n;i ++ )ans *= i;
return ans;
}
int main()
{
ll n,ans = 0;
cin >> n;
for(ll i = 1;i <= n;i ++ )
{
int num = fun(i);
if(num % 10 == 0)ans ++ ;
}
cout << ans << endl;
return 0;
}
数组的最大公约数
移步参考《最大公约数》
#include <iostream>
using namespace std;
const int N = 100000 + 10;
int a[N];
int gcd(int a,int b)
{
if(a % b == 0)return b;
else return gcd(b,a % b);
}
int main()
{
int n;
cin >> n;
for(int i = 1;i <= n;i ++ )cin >> a[i];
int ans = gcd(a[1],a[2]);
for(int i = 3;i <= n;i ++ )ans = gcd(ans,a[i]);
cout << ans << endl;
return 0;
}
古人的剩余定理
if、循环
#include <iostream>
using namespace std;
int main()
{
for(int i = 1;;i ++ )
{
if(i % 3 == 2 && i % 5 == 3 && i % 7 == 2)
{
cout << i << endl;
break;
}
}
return 0;
}
四边形坐标
公式计算
#include <iostream>
using namespace std;
double traS(int x1,int y1,int x2,int y2,int x3,int y3)
{
double S = 0.5 * abs(x1 * y2 - x1 * y3 + x2 * y3 - x2 * y1 + x3 * y1 - x3 * y2);
return S;
}
int main()
{
int x1,y1,x2,y2,x3,y3,x4,y4;
cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x4 >> y4;
double ans = traS(x1,y1,x2,y2,x3,y3) + traS(x2,y2,x3,y3,x4,y4) + traS(x1,y1,x2,y2,x4,y4) + traS(x1,y1,x3,y3,x4,y4);
printf("%.2lf",ans / 2.0);
return 0;
}
空间三角形
海伦公式,两点之间的距离公式
#include <iostream>
#include <cmath>
using namespace std;
double dis(double x1,double y1,double z1,double x2,double y2,double z2)
{
double s = sqrt(pow(x1 - x2,2) + pow(y1 - y2,2) + pow(z1 - z2,2));
return s;
}
int main()
{
double x1,y1,z1,x2,y2,z2,x3,y3,z3;
cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> x3 >> y3 >> z3;
double a = dis(x1,y1,z1,x2,y2,z2);
double b = dis(x1,y1,z1,x3,y3,z3);
double c = dis(x2,y2,z2,x3,y3,z3);
double p = (a + b + c) / 2;
double s = sqrt(p * (p - a) * (p - b) * (p - c));
printf("%.2lf",s);
return 0;
}
四叶玫瑰数
if语句
#include <iostream>
#include <cmath>
using namespace std;
bool judge(int n)
{
int t = n;
int ans = 0;
while(t > 0)
{
int num = t % 10;
ans += pow(num,4);
t /= 10;
}
if(ans == n)return true;
else return false;
}
int main()
{
int n;
cin >> n;
if(n == 1634 || n == 8208 || n == 9474)cout << "YES";
else cout << "NO";
return 0;
}
完美数字
if语句
#include <iostream>
#include <cmath>
using namespace std;
int fun(int n)
{
int mul = 1;
for(int i = 1;i <= n;i ++ )mul *= i;
return mul;
}
bool judge(int n)
{
int t = n,ans = 0;
while(t > 0)
{
int num = t % 10;
ans += fun(num);
t /= 10;
}
if(ans == n)return true;
else return false;
}
int main()
{
int n;
cin >> n;
if(judge(n))cout << "YES";
else cout << "NO";
return 0;
}
指定集合
if、循环
#include <iostream>
using namespace std;
const int N = 1000000 + 10;
int a[N];
int main()
{
int n,flag = 0;
cin >> n;
for(int i = 1;i <= n;i ++ )
{
cin >> a[i];
if(a[i] == 4 || a[i] == 5 || a[i] == 6)
{
flag = 1;
cout << a[i] << ' ';
}
}
if(flag == 0)cout << -1;
return 0;
}
阶乘数
循环,if
#include <iostream>
#include <cmath>
using namespace std;
int fun(int n)
{
int mul = 1;
for(int i = 1;i <= n;i ++ )mul *= i;
return mul;
}
int main()
{
int n;
cin >> n;
for(int i = 1;i <= 14;i ++ )
{
int num = fun(i);
if(num == n)
{
cout << "YES";
return 0;
}
else if(num < n)continue;
else break;
}
cout << "NO";
return 0;
}
真因子
if、循环
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int ans = 0;
for(int i = 1;i < n;i ++ )
{
if(n % i == 0)ans += i;
}
cout << ans << endl;
return 0;
}
平方根X
参考《非常大的N》中sqrt的函数用法与《向下取整》中floor函数的用法
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n;
cin >> n;
double num = sqrt(n);
if(num * num == n)cout << int(num);
else cout << int(floor(num));
return 0;
}
全部整除
循环、选择
#include <iostream>
using namespace std;
int gcd(int a,int b)
{
if(a % b == 0)return b;
else return gcd(b,a % b);
}
int lcd(int a,int b)
{
return (a * b) / (gcd(a,b));
}
int main()
{
int n;
cin >> n;
int ans = 0;
if(n == 1)
{
cout << 1;
return 0;
}
else
{
ans = lcd(1,2);
for(int i = 3;i <= n;i ++ )ans = lcd(ans,i);
}
cout << ans << endl;
return 0;
}