acm刷题踩坑记录和经验

一、数据类型表示范围判断和类型的忽略

对于常用的数据的输出类型判断:
int:-2147483648~+2147483647 (数据位数:10位)
unsigned int :0~4294967295 (数据位数:10位)
long long :-9223372036854775808~+9223372036854775807 (数据位数:19位)
unsigned long long:0~18446744073709551615 (数据位数:20位)
float:-3.4× 10^(-38) ~+3.4× 10^(+38) (7位有效数字)
double:-1.7×10^(-308) ~+1.7x10^(+308) (16位有效数字)

数据输出时使用printf函数容易犯的错误:输出类型的错误使用导致数据溢出。

错误示范:
long long a=3241938478237;
printf("%d",a);  //printf("%lld",a);正解

%lld 以十进制形式输出longlong类型;
%f 以十进制形式输出float类型;
%lf 以十进制形式输出double类型;
%d 以十进制形式输出有符号数;
%u 以十进制形式输出无符号数;
%o 以八进制形式输出无符号数;
%x 以十六进制形式输出无符号数。

二、malloc和new和calloc

malloc: 分配所需的内存空间,并返回一个指向它的指针,如果请求分配内存失败,则返回 NULL,free函数释放内存,如果要初始化内存为0,就要注意变量(结构体/数组/…)的初始值设定。

typedef struct node
{
    int count;
    struct node *next[26];
}*tree;
tree tem=(tree)malloc(1*sizeof(node));   //tem->count和tem->next[i]的初始值是不确定的


//
typedef struct node
{
    int count=0;
    struct node *next[26]={NULL};
}*tree;
tree tem=(tree)malloc(1*sizeof(node));   //tem->count和tem->next[i]的初始值是确定的

new:开辟的空间在堆上,分配所需的内存空间,并返回一个指向它的指针,如果请求分配内存失败,则返回 NULL,delete函数释放内存,如果要初始化内存为0,就要注意变量(结构体/数组/…)的初始值设定*

typedef struct node
{
    int count=0;
    struct node *next[26]={NULL};
}*tree,NODE;
tree tem=new NODE;   //tem->count和tem->next[i]的初始值是确定的(0/NULL)

calloc:分配所需的内存空间,并返回一个指向它的指针,如果请求分配内存失败,则返回 NULL.
//踩过这个坑,因为它能将分配的内存初始化为0!!!!使用new和malloc不会初始化内存为0!!
calloc() 函数将分配的内存全部初始化为零。如果不需要初始化,可以使用 malloc() 函数代替。另外,使用 calloc() 函数时需要注意,如果分配的内存块过大,可能会导致内存不足的问题。

typedef struct node
{
    int count;
    struct node *next[26];
}*tree;
tree tem=(tree)calloc(1,sizeof(node));   //tem->count和tem->next[i]的初始值是0/NULL.

三、pow函数

//一种优化 快速幂 
LL QuickPower2(LL a, LL n,int MOD){
	LL res = 1;
	while(n){
		if(n & 1) {
			res = quick_mul(res,a,MOD) % MOD;
		}
		a = quick_mul(a,a,MOD) % MOD;
		n >>= 1;
	}
	return res;
}

//快速相乘 
LL quick_mul(LL a,LL b,LL MOD){
	LL res = 0;
	while(b){
		if(b & 1){
			res = (res + a) % MOD;
		}
		a = (a + a) % MOD;
		b >>= 1;
	}
	return res;
}
//求a的e次方    a为整数 e大于等于0 使用时要注意定义的数据类型int的数据表达范围 
int power(int a, int e) {
    if (e == 0) return 1;  //特判 a的0次方为1 
    return e == 1 ? a : a * power(a, e-1);
}   //这个自己写的power函数效率比调用pow快很多 

在这里插入图片描述

四、圆周率值

PI=314159265358979323846264338327(无小数点)

五、向上取整–ceil

#include//头文件
#include 
#include 
using namespace std;//使用名字空间
//ceil只能对浮点数进行向上取整.
int main()//主程序
{
	int n,m,a;
	cin>>n>>m>>a;
	cout<<(long long)(ceil(n/(double)a)*ceil(m/(double)a));//直接输出
	return 0;
}

六、判断字母-

#include 
int main()
{
    char c;
    printf("输入一个字符: ");
    scanf("%c",&c);
 
    if( (c>='a' && c<='z') || (c>='A' && c<='Z'))
        printf("%c 是字母",c);
    else
        printf("%c 不是字母",c);
 
    return 0;
}

C 库函数 - isupper()
如果 c 是一个大写字母,则该函数返回非零值(true),否则返回 0(false)。

int isupper(int c);

C语言islower ()函数:判断字符是否为小写英文字母.
如果 c 是一个小写字母,则该函数返回非零值(true),否则返回 0(false)。

int islower(int c);

七、小根堆与大根堆

type:数据类型;
container:实现优先队列的底层容器;
function:元素之间的比较方式;

priority_queue< type, container, function >
//小根堆
//构造一个空的优先队列,此优先队列是一个小根堆
priority_queue<int,vector<int>,greater<int> > small_heap;   

/构造一个空的优先队列(此优先队列默认为大根堆)
priority_queue<int> big_heap; 

八、strlen超时

未TLE:

    int k=strlen(str+1);
    for( int i = 1; i <=k ; i++ )
    {
        h[i] = h[i - 1] * P + str[i]-'a'+1; // 计算字符串每个 前缀 的哈希值 
        p[i] = p[i - 1] * P; // 计算展开式中的各个权值 ( p^0, p^1 , p^2, p^3 ... ) 
    }

TLE:
原因是每次for循环都要进行strlen(str+1)来获取字符串长度导致的TLE

    for( int i = 1; i <=strlen(str+1); ; i++ )
    {
        h[i] = h[i - 1] * P + str[i]-'a'+1; // 计算字符串每个 前缀 的哈希值 
        p[i] = p[i - 1] * P; // 计算展开式中的各个权值 ( p^0, p^1 , p^2, p^3 ... ) 
    }

你可能感兴趣的:(CCPC,算法,数据结构)