解题中遇到的一些小知识点【杂记】

C++输出string

printf函数只能输出类型是 char * 的字符串,string类型的对象不止包含字符串,还包含了许多用于操作的函数,所以&str并非字符串的首地址,如需输出string对象中的字符串,可以使用string的成员函数c_str(),该函数返回字符串的首字符的地址。

    std::string a = "12345";
    printf("%s\n", a.c_str());
    char b[10] = {'1', '2', '3'};
    printf("%s\n", b);

实数运算函数

四舍五入函数 round()  周围
截尾函数    floor()  地板
收尾函数    ceil()  天花板

用位运算快速判断一个整数是否为2的n次幂

如果一个数是2^n,那么 ( n & (n-1) ) == 0 。 要注意位运算优先级低于等号。

bool func(int n){
	if ( ( n & (n-1) )==0 ) return 1;
		else return 0; 
}

如 8 & 7 ==0

  1000
& 0111
-------------
= 0000

用位运算判断奇数、偶数

取模运算的速度是非常慢的,所以我们用位运算代替取模。

	if ((a&1)==1) cout<<"奇数"<

计算机中的数字通常用二进制补码表示,不管是正数还是负数,最后一位如果是1,则为奇数,最后一位为0,则为偶数。
(补码转原码:保持符号位不动,其它各位取反+1,所以最后一位还是不变)

所以,判断一个数的奇偶性问题变成了判断最后一位是1还是0。
我们直接把这个待判断的N位数字与数字“1”相与,这样做可以使得前N-1位的结果都是0(因为数字1前N-1位是0),最后一位也就是第N位,与1相与,结果不变。
最终我们判断相与的结果,如果是1,则是奇数,是0,则是偶数。

进一步拓展:怎么判断两个数奇偶性是否相同?

相减!!奇偶性相同,差为偶数;奇偶性不同,差为奇数。

求一个数的所有因子之和

比如  25:1+5+25=31; 24=1+2+3+4+6+8+12+24=60

int func(int n){
	int sum=0;
	int i;
	for (i=1; i*i

有几个地方要注意:

算法复杂度是O(sqrt(n))的,也就是说我们只需要循环到sqrt(n),配对的另一个直接可以计算出来。

但是我们最好别用sqrt这个函数,而是写成 i * i < n 这种方式。

对于相同的因子,只计算一次,所以退出条件是 < n,而不是<=n。这样最后再特判一次。

gets和scanf

gets(s)函数与 scanf("%s",&s) 相似,但不完全相同,使用scanf("%s",&s) 函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止。

数组初始化

要用到#include
不管是一维还是二维数组都可以,但是前提数组空间要连续(要特别注意动态分配的数组)
memset(a,0,sizeof(a));

将一个数字转换成字符串

方法一:C语言的itoa(windows特有的)
#include
itoa(n,a,10);
n为要转换的数字,a为字符数组,可以是2-16进制的一个。 但是不能判断转换之后的字符数组的长度。

方法二:to_string函数
string s=to_string(n);

STL的sort调用

要用到#include 
sort(a+1,a+n+1,cmp);
第一个参数 数组名+起始位置
第二个参数 数组名+终止位置
cmp为自定义布尔函数
bool cmp(int a,int b) {
    return a>b;
}

大数组定义

定义数组的时候,太大的数组要在主函数外定义,不然,编译可以通过,运行会死掉。。。。

保留N位有效数字

#include
是I/O流控制头文件,就像C里面的格式化输出一样
cout< 保留6位有效数字


scanf读入

%d 输入十进制整数
%o 输入八进制整数
%x 输入十六进制整数
%u 输入无符号十进制整数
%f或%e 输入实型数(用小数形式或指数形式)
%c 输入单个字符
%s 输入字符串

scanf("%f",&a);  a必须是float类型
scanf("%lf",&a); a必须是double类型
不能混用。。。
所以一般的实数都用double来存储 输入输出都用lf吧
还有long long 要用%lld 读入 不然不对啊!!!!

或预算的性质

或运算只会越计算越大,值是一个递增的

求字符串长度strlen

char s[100];
int strlen(char *s){
    int i=0;
    while (s[i]!='\0') i++;
    return i;
}

exit强制退出

exit直接退出程序
需用头文件cstdlib

清空输出屏幕

system("cls");

一个规律

有两个数 a 和 b,求最大的小于等于 a 的且是 b 的倍数的数: a-a%b 
求最小的大于 a 的且是 b 的倍数的数: a-a%b+b

相加爆int

如果两个int类型的数相加,其和大于int,那么不仅需要把和用long long存储,两个加数起码一个要用long long存储。
两个int型相加会先计算出int型的和,然后再赋值给long long,所以即使和是用long long类型存储,也会丢失精度。
所以再相加前要先转换成long long类型。

你可能感兴趣的:(题目,杂记,c语言)