关于日期
日期变化
int dayOfMonth[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
// 是否是闰年
bool isLeapYear(int year) {
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
}
// 给当前日期加1天(注意参数都用了引用&,这样对参数的修改可以同步到函数外)
void addOneDay(int &year, int &month, int &day) {
day++; // 让day加1
if (day > dayOfMonth[isLeapYear(year)][month]) { // 如果超过当前月的天数
month++; // 让month加1
day = 1; // 重置day为1号
}
if (month > 12) { // 如果月份大于12
year++; // 让year加1
month = 1; // 重置month为1月
}
}
判断日期是否合法
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check_valid(int year, int month, int day)
{
if (month == 0 || month > 12) return false;
if (day == 0) return false;
if (month != 2)
{
if (day > days[month]) return false;
}
else
{
int leap = year % 100 && year % 4 == 0 || year % 400 == 0;
if (day > 28 + leap) return false;
}
return true;
}
例题
蓝桥杯跑步锻炼
#include<bits/stdc++.h>
using namespace std;
int ym[2][13]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
} ;
bool leapYear(int year)
{
return year%400==0||(year%4==0&&year%100);
}
int main()
{
int year=2000,month=1,day=1,week=6;
long long res=0;//不开longlong见祖宗//while(用逻辑或)
while(year!=2020||month!=10||day!=2)//跑到2020.10.1要包含这天就得往后延一天
{
if(day==1||week==1)res+=2;
else res++;
week++;day++;
if(week==8)week=1;
if(day>ym[leapYear(year)][month])//日动月变
{
day=1;
month++;
}
if(month>12)//月动年变
{
month=1;
year++;
}
}
cout<<res;
return 0;
}
周几(基姆拉尔森计算公式)
w表示星期,w的取值范围是0~6,0代表星期日,1~6星期一到星期六。
把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
#include<bits/stdc++.h>
using namespace std;
int f(int y ,int m,int d)
{
int w;
if (m==1 || m==2) {
m=(m==1?13:14);
y=y-1;
//此处表示把1,2月计算到上一年的13,14月
}
w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7;
return w;
}
int main()
{
int y,m,d;
scanf("%d-%d-%d",&y,&m,&d);
printf("%d",f(y,m,d));
return 0;
}
判断位数条件含2的个数
int get(int x){
int cnt = 0;
while(x){
if(x % 10 == 2) cnt ++ ;
x /= 10;
}
return cnt;
}
最大公约数
__gcd(a,b)
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
cout<<__gcd(a,b)<<endl;
}
欧几里得算法
int gcd(int a,int b) {
return b>0 ? gcd(b,a%b):a;
}
判断n的奇偶性的小方法
当n是偶数时候,二进制的末尾一定是0,那么&1的结果一定是false,同理
当n是奇数时候,二进制末位一定是1,那么结果一定是true
if (n & 1)//要求n为奇数时使用
if (n % 2)//要求n为奇数时使用
快速幂
int qmi(int a,int b,int q)
{
int res=1;
while(b)
{
if(b&1)res=(LL)res*a%p;
b>>=1;
a=(LL)a*a%p;
}
return res;
}
#define pi 3.14
const double pi=3.14
四舍六入五成双
一、具体计算规则:
(1)被修约的数字小于5时,该数字舍去;
(2)被修约的数字大于5时,则进位;
(3)被修约的数字等于5时,要看5前面的数字,若是奇数则进位,若是偶数则将5舍掉,即修约后末尾数字都成为偶数;若5的后面还有不为“0”的任何数,则此时无论5的前面是奇数还是偶数,均应进位。
9.8249=9.82, 9.82671=9.83
9.8350=9.84, 9.8351 =9.84
9.8250=9.82, 9.82501=9.83
关于不用参数交换a,b的值
a=a^b;
b=a^b;
a=a^b;
12.9
凯撒加密关于char类型溢出问题
#include<bits/stdc++.h>
using namespace std;
int main()
{ string s;
cin>>s;
int n;
cin>>n;
int len=s.length();
for(int i=0;i<len;i++)
{
if(s[i]>='a'&&s[i]<='z')
{
// s[i]=s[i]+n; 此处s[i]可能>127溢出
// if(s[i]>'z')s[i]=s[i]%122+96;
s[i]=(s[i]-'a'+n)%26+'a';
}
if(s[i]>='A'&&s[i]<='Z')
{
// s[i]=s[i]+n;
// if(s[i]>'Z')s[i]=s[i]%90+64;
s[i]=(s[i]-'A'+n)%26+'A';
}
}
cout<<s;
return 0;
}
进制转换
10–>k;
#include<bits/stdc++.h>
using namespace std;
int a[11];
int main()
{
int n,k,i=0;
cin>>n>>k;
do{
a[i++]=n%k;
n/=k;
}while(n);
for(int j=i-1;j>=0;j--){
if(a[j]<10)cout<<a[j];
else cout<<(char)(a[j]-10+'A');
}
return 0;
}
k–>10
#include <cstdio>
#include <cstring>
const int MAXN = 8;
char radixK[MAXN];
int main() {
int k;
scanf("%s %d", radixK, &k);
int radix10 = 0, base = 1, lenRadixK = strlen(radixK);
for (int i = lenRadixK - 1; i >= 0; i--) {
int thisPosition = (radixK[i] >= '0' && radixK[i] <= '9') ? (radixK[i] - '0') : (radixK[i] - 'A' + 10);
radix10 += thisPosition * base;
base *= k;
}
printf("%d", radix10);
return 0;
}
秦九韶算法 b进制转10进制
int get (string s,int b)
{
int res=0;
for(auto c:s)
res=res*b+c-'0';
return res;
}
数位排序
来源:第十三届蓝桥杯省赛C++C组 , 第十三届蓝桥杯省赛Java研究生组 , 第十三届蓝桥杯省赛PythonB/C组
cmp的应用
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N],b[N];
bool cmp(int x,int y)
{
return b[x]<b[y]||b[x]==b[y]&&x<y;
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
a[i]=i;
int num=i;
while(num)
{
b[i]+=num%10;
num/=10;
}
}
sort(a+1,a+n+1,cmp);
cout<<a[m];
return 0;
}
特殊时间
蓝桥模拟
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int a[4];
int main()
{
int res=0;
for(int i=0;i<=9;i++)
{
for(int j=0;j<=9;j++)
{
int as=0,b=0,c=0;
if(i==j)continue;
for(int pos=0;pos<4;pos++)//枚举b的位置
{
for(int idx=0;idx<4;idx++)//枚举四个位置所对应的下标
{
if(pos==idx)a[idx]=j;
else a[idx]=i;
}
as++;
int m=a[0]*10+a[1];
int d=a[2]*10+a[3];
if(m>=1&&m<=12&&d>=1&&d<=30)b++;
if(m>=0&&m<=23&&d>=0&&d<=59)c++;
}
res+=(as*b*c);
}
}
cout<<res;
}
stoi(),atoi() ,to_string 字符串处理函数,
前两者是将字符串转化为十进制 int 类型,
最者是将十进制类型 int、double 等转化为string,
stoi 的参数是 const string 类型
atoi 的参数是 const char 类型
stoi() 会对转化后的数进行检查,判断是否会超出 int 范围,如果超出范围就会报错;
atoi() 不会对转化后的数进行检查,超出上界,输出上界,超出下界,输出下界;
#include<iostream>
#include<cstring>
using namespace std;
int main() {
string s = "123";
int num1 = stoi(s);
int num2 = atoi(s.c_str());// 使用c_str()把string转化为const char*
cout << num1 << endl << num2 << endl;
return 0;
}
to_string()将数字常量(int,double,long等)转换为字符串(string)
#include<iostream>
#include<cstring>
using namespace std;
int main() {
int num = 123456789;
string s = to_string(num);
cout << s << endl;
return 0;
}
\\读取一行 不知结尾
while(cin>>m)a[cnt++]=m;