C/C++编程注意点
1.gets和scanf连用
如果在scanf后用gets需要注意一点,gets是遇到’\n’直接返回,而输入scanf后回车会将’\n’留在输入缓存里,
而gets正好遇到’\n’就直接返回了,所以你没有机会继续输入了。gets 在输入的时候,会结束循环。
C 库函数 - gets()
C 标准库 - <stdio.h>
描述
C 库函数 char *gets(char *str) 从标准输入 stdin 读取一行,并把它存储在 str 所指向的字符串中。当读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
2.闰年的判断方法
year%100==0||year%4==0&&i%100
3.long long 类型的输入输出
C:输入:scanf("I64d",&I)
输出:printf("I64d",s)
4.c++设置输出的精度问题
首先,需要包含头文件#include<iomanip>
,该头文件控制输入输出流的格式;
其次:setiosflags(ios::fixed)
与后面的setprecision(1)
连用可以控制输出小数小数点后面的位数。
另外,如果在输出的时候设置域宽,则使用setw()
函数,右对齐。
空出来的部分的填充内容setfill('0')
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
double pi = 3.1415926;
cout << setiosflags(ios::fixed) << setprecision(2) << pi << endl;
system("pause");
return 0;
}
#include <iostream>
#include <iomanip>
using namespace std;
int main( void )
{
const double value = 12.3456789;
cout << value << endl; // 默认以6精度,所以输出为 12.3457
cout< setprecision(4) << value << endl; // 改成4精度,所以输出为12.35
cout << setprecision(8) << value << endl; // 改成8精度,所以输出为12.345679
cout << fixed << setprecision(4) << value << endl; // 加了fixed意味着是固定点方式显示,所以这里的精度指的是小数位,输出为12.3457
cout << value << endl; // fixed和setprecision的作用还在,依然显示12.3457
cout.unsetf( ios::fixed ); // 去掉了fixed,所以精度恢复成整个数值的有效位数,显示为12.35
cout << value << endl;
cout.precision( 6 ); // 恢复成原来的样子,输出为12.3457
cout << value << endl;
}
C++ 域宽
需要头文件#include <iomanip>
Setw(6)
C语言精度问题
%.2d
输出整形时最少输出2位,如果不够前面以补0占位。如输出2时变成02。200时只输出200;输出浮点型时(%.2f)小数点后强制2位输出,
%2d
输出占2个位置,如输出2时,是一个空格和2,如200时输出200
%2d是将数字按宽度为2,采用右对齐方式输出,若数据位数不到2位,则左边补空格
5.abs()函数 abs(x)
1.返回x的绝对值。
2.x为数字型表达式
3.返回值为数字
不同类型的数据使用不同类型的绝对值函数:
整型:
int abs(int i)
//返回整型参数i的绝对值
复数:
double cabs(struct complex znum)
//返回复数znum的绝对值
双精度浮点型:
double fabs(double x)
//返回双精度参数x的绝对值
长整型:
long labs(long n)
//返回长整型参数n的绝对值
6.%s
在使用scanf()函数输入字符串的时候,地址列表直接写字符数组的名字。
输出字符数组的时候,printf()函数中的输出项是字符数组名,不是数组元素名。
利用%s输入字符串不能接收空格,c语言规定,scanf()函数遇到空格或回车就结束本次输入。
7.数组
定义数组时不能使用变量。
下列定义方法不能允许:
int n;
scanf("%d",&n);
int a[n];
8.将字符型转换为整型的办法
1)减去一个‘0’
2)减去一个48
9.strlen 和sizeof 的区别
1)strlen 是函数 ,sizeof是运算符。
2) strlen 是测量的是字符的实际长度,以‘\0’结束。而sizeof测量的是字符的分配大小(存储空间)。
10.在进行次方运算时,使用pow()函数。
并且要使用#include <math.h>
作头文件。
11.定义字符串类型,不用为它指定分配空间的首地址。
12.二进制转八进制(取三合一)
方法为:3位进制数按权展开相加得到1位数八进制数(注意事项: 3位二进制转成八进制是从右到左开始转换,不足时补0)
13.二进制转十六进制(取四合一)
4位二进制转成十六进制是从右到左开始转换的,不足时补0.
14. i&1
当一个数是奇数时,返回1
是偶数时,返回0
15. int , float , double , long , long long , usigned 的取值范围
int: 4byte = 32 bit有符号signed范围:2^31-1 ~ -2^31即:2147483647 ~ -2147483648无符号unsigned范围:2^32-1 ~ 0即:4294967295 ~ 0
long: 4 byte = 32 bit同int型
double: 8 byte = 64 bit范围:1.79769e+308 ~ 2.22507e-308
long double: 12 byte = 96 bit范围: 1.18973e+4932 ~ 3.3621e-4932
float: 4 byte = 32 bit范围: 3.40282e+038 ~ 1.17549e-038
long long的最大值:9223372036854775807(>10^18)
long long的最小值:-9223372036854775808
unsigned long long的最大值:18446744073709551615
__int64的最大值:9223372036854775807
__int64的最小值:-9223372036854775808
unsigned __int64的最大值:18446744073709551615
16.sort()函数
1、头文件:#include<algorithm>
2、时间复杂度:类似于快排,为nlog(2)n,效率较高
3、sort函数有三个参数:
(1)要排序数组的起始地址
(2)要排序数组的最后一个数据元素的下一个地址
(3)排序方法,如果没有排序方法的话,默认从小到大排序
1.sort函数实现数的排序
sort(arr,arr+10,cmp)
;
2、sort函数实现字符串的排序(根据长度,字母顺序两种情况)
(1)sort函数对string内的字符进行排序(string为字符串类型数据)
sort(s.begin(),s.end());///从小到大
cout<<s<<endl;
sort(s.begin(),s.end(),cmp);///从大到小
cout<<s<<endl;
(2)sort对一维字符数组内的字符进行排序
sort(s.begin(),s.end());///从小到大
cout<<s<<endl;
sort(s.begin(),s.end(),cmp);///从大到小
cout<<s<<endl;
(3)sort对string类型的数组按照字典序排序
sort(s,s+12);///字符串默认按照字典序从小到大排序,数默认按照大小从小到大排序
sort(s,s+12,cmp);///按照字典序从大到小排序
(4)sort对char类型的二维数组进行字典序排序
错误,不能这样做。同样也不能进行根据字符串长度的排序. 解决方法有:1、使用qsort 2、改用string
(5)sort对string类型的数组根据长度进行排序
sort(s,s+12,cmp1);///按照长度从小到大排序
sort(s,s+12,cmp2);///按照长度从大到小排序
6、对结构体数组进行排序(根据结构体中的某元素)
sort(stu,stu+n,cmp);
sort(begin, end, cmp)
,其中begin为指向待sort()的数组的第一个元素的指针,end为指向待sort()的数组的最后一个元素的下一个位置的指针,cmp参数为排序准则,如果没有的话,默认以非降序排序。
以int为例的基本数据类型的sort()使用
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int a[5] = {
1, 3, 4, 2, 5};
sort(a, a + 5);
for (int i = 0; i < 5; i++) cout << a[i] << ' ';
return 0;
输出结果为:1 2 3 4 5
自定义cmp参数
#include <iostream>
#include <algorithm>
using namespace std;
bool cmp(int x, int y) {
return x > y;
}
int main() {
int a[5] = {
1, 3, 4, 2, 5};
sort(a, a + 5, cmp);
for (int i = 0; i < 5; i++) cout << a[i] << ' ';
return 0;
}
输出结果为:5 4 3 2 1
17. unique函数
在STL中unique
函数是一个去重函数, unique
的功能是去除相邻的重复元素(只保留一个),其实它并不真正把重复的元素删除,是把重复的元素移到后面去了,然后依然保存到了原数组中,然后 返回去重后最后一个元素的地址,因为unique
去除的是相邻的重复元素,所以一般用之前都会要排一下序。
注意,words的大小并没有改变,依然保存着10个元素;只是这些元素的顺序改变了。调用unique
“删除”了相邻的重复值。给“删除”加上引号是因为unique实际上并没有删除任何元素,而是将无重复的元素复制到序列的前段,从而覆盖相邻的重复元素。unique
返回的迭代器指向超出无重复的元素范围末端的下一个位置。
注意:算法不直接修改容器的大小。如果需要添加或删除元素,则必须使用容器操作。
个人感觉,unique
是STL中很实用的函数之一,需要#include <algorithm>
,下面来简单介绍一下它的作用。
unique
的作用是“去掉”容器中相邻元素的重复元素,这里去掉要加一个引号,为什么呢,是因为它实质上是一个伪去除,它会把重复的元素添加到容器末尾,而返回值是去重之后的尾地址(是地址!!),举个例子:
1.int num[10]={
1,1,2,2,2,3,4,5,5,5};
2.int ans=unique(num,num+10)-num;
3.
所以要将unique()后的函数,用unique的返回值去减去首地址。就可输出去重之后的值了。
18.c++ cin cin.getline() getline()的用法
一、cin>>
用法1:输入一个数字或字符
用法2:接收一个字符串,遇“空格”、“TAB”、“回车”就结束
二、cin.getline()
用法:接收一个字符串,可以接收空格并输出
#include <iostream>
using namespace std;
main ()
{
char m[20];
cin.getline(m,5);
cout<<m<<endl;
}
接收5个字符到m中,其中最后一个为'\0',所以只看到4个字符输出;
延伸:
1、cin.getline()
实际上有三个参数,cin.getline(接收字符串的变量,接收字符个数,结束字符)
2、当第三个参数省略时,系统默认为'\0'
3、如果将例子中cin.getline()
改为cin.getline(m,5,'a');
当输入jlkjkljkl时输出jklj,输入jkaljkljkl时,输出jk。
三、getline()
用法:接收一个字符串,可以接收空格并输出,需包含“#include <string>”
#include<iostream>
#include<string>
using namespace std;
main ()
{
string str;
getline(cin,str);
cout<<str<<endl;
}
四、注意的问题
1、cin.getline()
属于istream流,而getline()属于string流,是不一样的两个函数
2、当同时使用cin>>
,getline()
时,需要注意的是,在cin>>
输入流完成之后,getline()
之前,需要通过
方法一:str="\n"; getline(cin,str);
方法二:cin.clear(); cin.sync();
的方式作为输入流cin以清除缓存,如果不这样做的话,在控制台上就不会出现getline()的输入提示,而直接跳过,因为程序默认地将之前的变量作为输入流。
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main(){
string s1; string s2;
cin>>s1;
cout << "s1 is :" << s1 << endl;
getline(cin, s2); cout << "s2 is :" << s2 << endl;
system("pause");return 0;
}
#include<iostream>
#include<string>
#include<sstream>using namespace std;
int main(){
string s1;
string s2;
cin>>s1;
cout << "s1 is :" << s1 << endl;
cin.clear();cin.sync();getline(cin, s2); cout << "s2 is :" << s2 << endl; system("pause");
return 0;
}
C语言清除缓存fflush(stdin);//清除缓冲区
19. while(scanf("%s", map[r]) != EOF)
1.在黑框中手动输入时,系统并不知道什么时候到达了所谓的“文件末尾“,因此需要用< Ctrl + Z >组合键,然后按< Enter >键的方式来告诉系统已经到了 EOF,这样系统才会结束 while
2. while((str[i]=getchar())!=’\n’)
20.四舍五入问题
floor : 不大于自变量的最大整数
ceil :不小于自变量的最大整数
round:四舍五入到最邻近的整数
这里看很多人说不能直接用round这个函数,所以写了具体模板代码,比如这样
double round(double r)
{
return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
}
在目前的测试中round
是可以用的,VS里也有这个内置函数。
备注:
1、这部分处理需要加math
头文件
2、四舍五入进位到整数部分
重点时备注2,也就是说这三个函数的结果都是整数,小数位都会进位。比如4.085÷2 = 2.0425,通过round之后,结果是2.000000。如果需要精确到某一个小数位的四舍五入,直接用会有问题,可以通过放缩处理,先扩大成整数再缩小为小数。当然,自己学艺不精,应该有自己没了解的更好的办法
21.%g的用法
g格式 符,用来输出实数,输出格式为f格式或e格式,系统根据数据占宽度m大小,自动选择占宽度较小的某种格式输出,g格式符不输出小数点后无意义的零。
例:
main()
{
float x=654.321;
printf("%f,%e,%g",x,x,x);
}
打印输出:654.320984,6.543210e+002,654.321(其中输出的654.320984是因为在内存中的存储误差引起的)
21.C语言中随机数的生成
随机数的生成
在C语言中有可以产生随机数的函数,需要添加stdlib.h
和time.h
头文件。首先在main
函数开头加上“srand((unsigned)time(NULL));”
,这个语句将生成随机数的种子。然后,在需要生成随机数的地方使用rand()
函数。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
using namespace std;
int main(){
srand((unsigned)time(NULL));
for(int i = 0; i < 10; i++){
printf("%d ",rand());
}
return 0;
}
rand()
函数只能生成[0,RAND_MAX]
范围内的整数(RAND_MAX
是stdlib.h
中的一个常数,在不同的系统中会有所不同),因此,如果想要输出给定范围[a,b]
内的随机数,需要使用rand()%(b-a+1)+a
,其中rand()%(b-a+1)
可以输出[0,b-a]内的随机数,再+a则可以输出[a,b]
内的随机数。
但是,以上的方法仅仅对左右端点相差不超过RAND_MAX
的区间的随机数有效,如果需要生成更大的数就不行了。想要生成大范围的随机数有很多种方法,这里记录一种:
- 先用rand()生成一个[0,RAND_MAX]范围内的随机数
- 然后用这个随机数除以RAND_MAX,这样就会得到一个[0,1]范围内的浮点数
- 再用这个浮点数乘以范围长度(b-a+1),在加上a即可
即(int)((double)rand()/RAND_MAX*(b-a+a)+a)
22.数组的初始化注意
A[100001]={1};的意思是将第一个赋值为1其余都为0.
数组不能越界赋值。
23. scanf(“%1d”,&a)
表示指定输入数据的列宽,1d表示数据的列宽为1。比如当我们输入的数据是234的时候,假设你的输入是scanf(“%1d”,&a),这样系统会自动截取2赋给变量a
23. C++ stringstream 实现字符与数字之间的转换
1.字符串转数字
#include<iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
//字符转数字
string str1 = "2018219";
string str2 = "2018.219";//浮点数转换后的有效数为6位
int num1 = 0;
double num2 = 0.0;
stringstream s;
//转换为int类型
s << str1;
s >> num1;
//转换为double类型
s.clear();
s << str2;
s >> num2;
cout << num1 << "\n" << num2 << endl;
return 0;
}
2.数字转字符串
#include "stdafx.h"
#include<iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
string str1;
string str2 ;
int num1 = 2018219;
double num2 = 2018.219;
stringstream s;
s << num1;
s >> str1;
s.clear();
s << num2;
s >> str2;
cout << str1 << "\n" << str2 << endl;
return 0;
}
//重复使用注意将转换的s用s.clear()清空
24. a和A对应的ASCII码数值分别是多少,相差多少
A的ASCII码是65,a的ASCII码是97;ASCII码表中,一个字母的大小写数值相差32,一般知道大写字母的ASCII码数值,其对应的小写字母的ASCII码数值就算出来了,是大写字母的ASCII码数值“+32”。字符串中的字符不符合
25.STL中set的用法
其实这题用STL中的set(集合)做是再简单不过了
set,顾名思义,就是数学上的集合——每个元素最多只出现一次,并且set中的元素已经从小到大排好序。
头文件:#include < set >
//用bits的童鞋请忽略
常用操作 :
begin()
返回set容器的第一个元素的 地址
end()
返回set容器的最后一个元素 **地址 **
clear()
删除set容器中的所有的元素
empty()
判断set容器是否为空
max_size()
返回set容器可能包含的元素最大个数
size()
返回当前set容器中的元素个数
erase(it)
删除迭代器指针it处元素
insert(a)
插入某个元素
更多关set的用法详见
26. c函数strcpy() ,strcat(),strcmp(), strlen(), strchr() ,strstr() 使用整理
1.strcpy()
功能: 字符串复制
头文件: string.h
返回值类型: char*
C语言标准库函数strcpy,把从src地址开始且含有’\0’结束符的字符串复制到以dest开始的地址空间。
原型声明:char strcpy(char dest, const char *src);
头文件:#include <string.h>
和#include <stdio.h>
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
//
//C语言标准库函数strcpy的一种典型的工业级的最简实现。
//返回值:目标串的地址。
//对于出现异常的情况ANSI-C99标准并未定义,故由实现者决定返回值,通常为NULL。
//参数:des为目标字符串,source为原字符串。
char* strcpy(char* des,const char* source)
{
char* r=des;
assert((des != NULL) && (source != NULL));
while((*des++ = *source++)!='\0');
return r;
}
while((*des++=*source++))
;的解释:赋值表达式返回左操作数,所以在赋值NULL后,循环停止。
比如:
1.char arr1[] = "asdfghj";
2.char *p = "123456";
3.strcpy(arr1,p);
4.printf("%s\n",arr1);
2.strcat()
原型
extern char *strcat(char *dest,char *src);
头文件
#include <string.h>
在C++中,则存在于<cstring>
头文件中。
功能
(把两个字符串连接起来)
把src所指字符串添加到dest结尾处(覆盖dest结尾处的’\0’)。
说明
src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
1.int i=0,j=0;
2.printf(“请输入两个整数:”);
3.scanf("%d %d",&i,&j);
4.char arr[20] = “hello”;
5.strcat(arr," world");
6.printf("%s\n",arr);
3.strcmp()
C/C++函数,比较两个字符串
设这两个字符串为str1,str2,
若str1=str2,则返回零;
若str1<str2,则返回负数;
若str1>str2,则返回正数。
功 能
比较字符串s1和s2
头文件
string.h
一般形式
strcmp(字符串1,字符串2)
#include <stdio.h>
#include <string.h>
int main()
{
char string[20];
char str[3][20];// 特别注意:strcmp(const char *s1,const char * s2)这里面只能比较字符串,即可用于比较两个字符串常量,或比较数组和字符串常量,不能比较数字等其他形式的参数。
int i;
for(i=0;i<3;i++)
gets(str[i]);
if(strcmp(str[0],str[1])>0)
strcpy(string,str[0]);
else
strcpy(string,str[1]);
if(strcmp(str[2],string)>0)
strcpy(string,str[2]);
printf("\nThe largest string is%s\n",string);
return 0;
}
4.strlen()
extern unsigned int strlen(char *s);
在Visual C++ 6.0中,原型为size_t strlen(const char *string); ,其中size_t实际上是unsigned int,在VC6.0中可以看到这样的代码:typedef unsigned int size_t; 。
头文件:string.h
格式:strlen (字符数组名)
功能:计算给定字符串的(unsigned int型)长度,不包括’\0’在内
说明:返回s的长度,不包括结束符NULL。
相关函数:
TCHAR.H routine _UNICODE & _MBCS not defined_MBCS defined_UNICODE defined_tcslen
strlen strlen wcslen
_tcsclen strlen _mbslen wcslen
5.strchr()
char strchr(const char _Str,int _Val)
char strchr(char _Str,int _Ch)
头文件:#include <string.h>
功能:查找字符串s中首次出现字符c的位置
说明:返回首次出现c的位置的指针,返回的地址是被查找字符串指针开始的第一个与Val相同字符的指针,如果s中不存在c则返回NULL。
返回值:成功则返回要查找字符第一次出现的位置,失败返回NULL
6.strstr()(功能是在字符串中查找)
包含文件:string.h
函数名: strstr
函数原型:
1 extern char *strstr(char *str1, const char *str2);
语法:
1 * strstr(str1,str2)
str1: 被查找目标 string expression to search.
str2: 要查找对象 The string expression to find.
返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。
例子:
1
2
3 char str[]=“1234xyz”;
char *str1=strstr(str,“34”);
cout << str1 << endl;
显示的是: 34xyz
注意合理使用strchr和strstr,两者是有区别的,简单来说,strchr只输出要查找的字符串,而strstr输出要查找的字符串和它之后的字符。
答案是ABC\0 因为strcpy会运行到\0出就停止。
27.tolower()与toupper()
C++中的tolower()
函数与toupper()
函数
https://blog.csdn.net/weixin_41053564/article/details/81349353
在C++语言中tolower()
函数是把字符串都转化为小写字母
touppre()
函数是把字符串都转化为大写字母
其中需要注意的是:这两个函数的声明在头文件<cctype>
中
但是经过测试,如果不包含头文件<cctype>
仅仅有<iostream>
也是可以的
28. isupper()
判断字符中的字母是否为大写:
是,返回1
不是,返回0
29.字符字母的大小写转换的方法
今天做一道题,要用string类,涉及大小写转换,查看了C++文档,string类没有提供这样的方法,只好自己写。
之后是想到一个比较笨的方法,我把string当成一个容器,然后用迭代器一个一个来替换。
比如下面的是大写转小写:
string temp;
string::iterator it;
for (it = temp.begin(); it != temp.end(); it++)
if ((*it) < 'a')
*it = *it + 32;
测试一下代码:
#include<iostream>
#include<string>
using namespace std;
int main(void)
{
string temp;
string::iterator it;
cin >> temp;
for (it = temp.begin(); it != temp.end(); it++) //大写转小写
if ((*it) < 'a')
*it = *it + 32;
cout <<"转换成小写之后" <<temp << endl;
for (it = temp.begin(); it != temp.end(); it++) //小写转大写
if ((*it) > 'Z')
*it = *it - 32;
cout <<"转换成大写之后" <<temp << endl;
return 0;
}
测试输入
AsdFghJkL
测试输出
转换成小写之后asdfghjkl
转换成大写之后ASDFGHJKL
29.C++标准库中的find()函数
需要#include <algorithm>
泛型算法的 find:
在非string类型的容器里,可以直接找出所对应的元素.
find函数需要几个参数:迭代器,下标值,所要找的元素
vector<int> a;
find(a.begin(),a.end(),1);
这句话就表示从a的头开始一直到尾,找到第一个值为1的元素,返回的是一个指向该元素的迭代器。
find在string容器中用途比较广:
find_first_of,find_last_of,find_not_first_of,find_not_last_of
等等
在string类型中,需要的参数也有迭代器,下标和要找的字符串,这里要注意,是字符串,不能查找单个字符。
string a;
find(a.begin(),a.end(),"asd")
这句话就是说,在a中找到第一个存在子串与"asd"子串相等的字符串的首地址。返回指向该字符串首地址的迭代器。
find_last_of
则是找到最后一个,
find_not_first_of
是找出第一个不与“asd”相等的字符串的首地址
30.<<左移符号,>>右移符号。
不越界的情况下,左移一位相当于乘2,右移一位相当于除以2;
31.使用宏的另外一种用法:构造语句。方法:
#define xh(i,a,b) for(int i=a;i<=b;i++)
32.全排列运用next_permutation(strat,end)
next_permutation(strat,end)
是#include <algorithm>
库中标准函数,它可以表示[start,end)
内存的数组中严格的产生下一个字典序。next_permutation(strat,end)
是有返回值的,没有下一个字典序返回0
33.nth_element()求第k小的数
在 STL 里有一个神奇的函数 nth_element。
它的用法是 nth_element(a+x,a+x+y,a+x+len);
。
执行之后数组 a 下标 xx 到 x+y-1 的元素都小于 a[x+y],下标 x+y+1到 x+len-1的元素 都大于 a[x+y],但不保证数组有序。此时 a[x+y]就是数组区间 x到 x+len-1 中第 y 小的数,当然也可以自己定义 cmp 函数。
3、数论做法 卡特兰/CatalanCatalan
既然很多Dalao都说过,那我直接给式子了;
递推式1:
f[n]=f[0]*f[n-1] + f[1]f[n-2] + … + f[n-1]f[0] (n≥2)f[n]=f[0]∗f[n−1]+f[1]∗f[n−2]+…+f[n−1]∗f0
然后按照这个递推式模拟就好了(代码后面给)
既然上面标了1,那就有递推式2~
递推式2:
h[n]=h[n-1](4n-2)/(n+1)h[n]=h[n−1]∗(4∗n−2)/(n+1)
依旧按式子模拟(代码后面给)
既然有2,那再来个3吧~
递推式3:
h[n]=C[2n,n]/(n+1) (n=0,1,2,…)h[n]=C[2n,n]/(n+1)(n=0,1,2,…),CC是组合数
PS:C[m,n]=C[m-1,n-1]+C[m-1,n]PS:C[m,n]=C[m−1,n−1]+C[m−1,n]:且规定: C[n,0]=1 C[n,n]=1 C[0,0]=1C[n,0]=1C[n,n]=1C[0,0]=1
这个公式也叫组合数公式(下面那个也是)
(不知道组合数可以百度)
于是仍然把标程放到最后~
递推式4:
h[n]=C[2n,n]-C[2n,n-1] (n=0,1,2,…)h[n]=C[2n,n]−C2n,n−1 组合数CC不解释了;
34.0x7fffffff
-2147483649
35. 与或非(短路原则)
与,只要一个为假就不进行运算
或,只要一个为真就为真,就不往后判断
36. 位运算符
& 只要一个为假就为假
|只要一个为真就为真
~反
^相同为false 不同为true
37. 交换两个数的方法:
a=a^b;
b=a^b;
a=a^b;
第二次^异或数据还原
38.ios::sync_with_stdio(false);
这个方法还是要解释一下的
在某些题目中,我们使用普通的cin
和cout
会超时,所以我们每次只能打scanf
和printf
,然后一堆的占位符巨麻烦),为什么cin
和cout
比scanf
和printf
用的时间多? 这是因为C++中,cin
和cout
要与stdio
同步,中间会有一个缓冲,所以导致cin
,cout
语句输入输出缓慢,这时就可以用这个语句,取消cin
,cout
与stdio
的同步,说白了就是提速,效率基本与scanf
和printf
一致。
39.exit(0)的意思指的是正常状态退出。
需要头文件#include <cstdlib>
需要指定参数返回类型,但在如果把exit用在main
内的时候无论main
是否定义成void返回的值都是有效的,并且exit不需要考虑类型,exit⑴
等价于return ⑴
。
exit()
就是退出,传入的参数是程序退出时的状态码,0表示正常退出,其他表示非正常退出。退出程序,括号中的0表示程序的退出返回代码,无实际意义。exit()
就是退出 , 0就是返回的参数, 也可以返回 1 -1 等 你可以用来判断函数是否正确返回
40. while(~scanf("%d", &n))
~是按位取反
scanf的返回值是输入值的个数
如果没有输入值就是返回-1
-1按位取反结果是0
while(~scanf("%d", &n))
就是当没有输入的时候退出循环
EOF
,为End Of File的缩写,通常在文本的最后存在此字符表示资料结束。
EOF 的值通常为 -1
41.cin.get()
cin.get()是保留回车在输入流队列中的
42.%-d 左对齐
一般是右对齐
43.链式星存图
#include <iostream>
#include <queue>
#include <climits>
#include <utility>
using namespace std;
const int N=1e5+5;
const int M=2e5+5;
int head[N],nxt[M],to[M],val[M],cnt;
int d[N],v[N],n,m,s;
priority_queue<pair<int,int> > q;
void add(int a,int b,int c){
nxt[++cnt]=head[a];
to[cnt]=b;
val[cnt]=c;
head[a]=cnt;
}
void dijkstra(){
for(int i=1;i<=n;i++) d[i]=INT_MAX;
d[s]=0;
q.push(make_pair(0,s));
while(!q.empty()){
int u=q.top().second;
q.pop();
if(v[u]) continue;
v[u]=1;
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
int w=val[i];
if(d[v]>d[u]+w){
d[v]=d[u]+w;
q.push(make_pair(-d[v],v));
}
}
}
}
int main()
{
cin>>n>>m>>s;
for (int i = 1; i <=m ; ++i) {
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
}
dijkstra();
for (int i = 1; i <=n ; ++i) {
if(d[i]==0x3f3f3f3f)
cout<<2147483647<<' ';
else
cout<<d[i]<<' ';
}
return 0;
}