C笔记

1.scanf()后面加gets时,需要在scanf后面加上getchar。但是gets和gets之间不用
  scanf("%c")前面如果有回车,要在前面加getchar()  scanf("%s")不需要
  cin >> str ;遇到空格结束   getline( cin , str );遇回车结束
  getline(cin,s)前面有回车要getchar()  getline和getline之间不用

  gets getline(cin,s) scanf("%c") 会吸收回车(之前有回车会吸收,最后的回车会吸收)

2.x个白球,y个黑球,有(x+y)!/x!/y!种排法

4.傻子错误:if(a=0)   scanf("%d",a)   x[100,100] 设置全局变量后在main函数里再次定义

5.错排公式:D(n)=n![(-1)^2/2!+...+(-1)^n/n!]=n!/e+0.5取整

6.# define N 3+3      main N*N    结果为 15  :3+3*3+3  宏替换
  # define f(x) x*x   main f(2+2) 结果为 8   :2+2*2+2  宏替换 

8.汉罗塔:①只能移一格:n个从a到c:3^n -1  
                       从a到b:(3^n -1)/2

9.输入“字符串 数 数”可以用scanf("%s%lf%lf",a,&x,&y):遇到空格自动断开

10.unsigned int f[10][V];//全局变量,自动初始化为0

11.结构体名a,用a.num引用,如果是结构体指针b,用b->num引用

12.memcmp(ss[i],ss[j],k)==0//注意这个函数的作用是判断两个字符串在前k个字符是否相等。

13.memcpy(y,x,len);把x的前len个复制到y中。

15.过山车:男生找一个女生,如果女生没有被人找过,配对;如果被找过,看看找这个女生的男生能不能再找一个女生。

17.sotr(&a[0],&a[50])||sort(a,a+50);    #include<algorithm> using namespace std;

18.num=x.substr(p,i-p);//x的p开始,长为i-p

   x.replace(p,i-p,"111");//x的p开始,长为i-p的地方换成111

   x.insert(0,"j");//x的第0个位置插入j字符串
   x.insert(0,9,'J');//插入9个字符

   s.find(s1,2)从第二位即s[2]找起找到的第一个s1的位置(如果找到的s1的第一个字符排字符串第一个就是0)
   s.rfind(s1)从最后开始找找到的第一个s1
   if(a.find("g")!=std::string::npos)cout<<a.find("g")<<endl;
   else cout<<"goodbye!"<<endl;

   s1.compare(s2);或者直接>,<
   s.append(9,'n')swap(s1,s2);

   s1.erase(位置,长度)

1. const char* 和string 转换
(1) const char*转换为 string,直接赋值即可。
     EX: const char* tmp = "tsinghua".
            string s = tmp;
(2) string转换为const char*,利用c_str()
    EX:  string s = "tsinghua";
           const char*tmp = s.c_str();
2. char*const char*之间的转换
(1) const char*转化为char*,利用const_cast<char*>
     EX: const char* tmp = "tsinghua";
             char* p = const_cast<char*>(tmp);
(2) char*转化为const char*,直接赋值即可。
     char* p = "tsinghua".
     const char* tmp = p;
3. char*和string之间的转换
  有了12的基础,char*和string转化就很简单了。
(1)char*转化为string,直接赋值即可。
     EX: char* p = "tsinghua".
            string str = p;
(2)string转化为char*,走两步,先是string->const char*,然后是const char*->char*
     EX:  string str = "tsinghua";
             char* p = const_cast<char*>(str.c_str()):

20.<sstream> stringstream ss; string a= "11";  int b;  ss << a; ss >> b;注意ss要打在前面
   “aa11”-> int ,int == -1;"11aa"->int,int==11;

21.<cstdlib>  itoa( int , *char , 进制)long long->lltoa( )

22.%p 不同于%x 的是一致输出8位十六进制数
   //770d30 770D34      %x %X 输出
   //00770D30 00770D34  %p输出,固定大写,不能用%P
   long long:scanf("%llX",&a);printf("%llX\n",a);

23.scanf("%d %d",&p->t1,&p->t2);  //p为指针
   printf("%d %d\n",p->t1,p->t2); //对结构体包含变量的输入输出
   
25.求对应角度:asin(sqrt(3)/2)*180/PI=60

26.三角形面积公式:S = sqrt(p*(p-a)*(p-b)*(p-c)) (p=(a+b+c)/2)

27.*(P+i)=p;   //P为二维指针,p是一维指针*(p+i)表示第i个一维数组的首地址

28.int **P=(int**)malloc(sizeof(int*))*(P+i)=p;//当二维指针没有规定指向时,不能用*(取值)

29.int *p[2]   p是包含两个元素的指针数组,表示2行n列 int a[3],b[4];p[0]=a;p[1]=b;
   int (*p)[2] p表示n行2*(*(p+0)+0) *(*(p+0)+1) *(*(p+n)+0) *(*(p+n)+1);

32.float a=0.5;    scanf("%.0f\n",a);  输出结果为1,浮点取位时会四舍五入

33.a个数里面b个是错的
   ①a里面选出b个 t=Jie(a)/Jie(a-b)/Jie(b)  ②b个进行错排 t*=Cuo(b)

36.在函数参数写为与全局参数相同类型的局部参数时,本函数不能想要改变的全局参数
   全局:struct people{int t;} a[10];                全局:struct people{int t;} a[10];       
   函数:void s(people aa)             错误,改为    函数:void s(int ii)          
         {aa.t++;}                                         {a[ii].t++;}    //函数内明确写为全局参数
   调用:s(a[0]);                                    调用:s(ii);

37.卡特兰数h(n)=h(0)*h(n-1)+h(1)*h(n-2)....   eg:h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0) h(0)=h(1)=1;
   递推:h(n)=h(n-1)*(4*n-2)/(n+1)    通项:h(n)=C(2n,n)/(n+1)C(2n,n)-c(2n,n-1)

   应用:1.n个数进栈,有h(n)种出栈方式;
         2.凸n边形,用多条不相交的对角线分成三角形,有h(n-2)种可能性;
         3.n个节点,有h(n)种不同的二叉搜索树
         4.给n对括号排序,有h(n)种不同的正确的排序方式

40.a[2][2]  swap(a[0],a[1])  交换两行

44.ios::sync_with_stdio(false);   #include<cstdio>  用于关闭同步,简化cin的时间
	关同步后最好全部用cin、cout,别用scanf和printf

47.排列组合公式 A(a,b)=a!/(a-b)!排列      C(a,b)=a!/b!/(a-b)!组合

49.pair可以用来保存sort前的下标

51.位运算优先级较低,故需要括号加持:i&(j<<2)==2->  (i&(j<<2))==2
   
52.二维数组new delete 
   int *p1 = new int[10];   
   int (*x)[n] = new int[m][n];        
     ...   
    delete []x; 

53.#ifndef标识符
   程序段1
   #else
   程序段2
   #endif

   它的功能是,如果标识符没有被#define命令定义过则对程序段1进行编译;
   否则对程序段2进行编译。如果没有程序段2(它为空),本格式中的#else可以没有,即可以写为:

   #ifndef标识符
   程序段
   #endif 

54.函数参数是list时,也要加&才能通过函数修改list内容。即stl容器也是值传递,用法等同int55.获得 n 的第 i 位的数据(0还是1),判断(n&1<<i)),若真,为1,假,为0;
   设置 n 的第 i 位为1,n=(n |1<<i));
   设置 n 的第 i 位为0,n=(n &~1<<i));
   取出 n 的最后一个1 (lowbit):(n &-n)) (这里利用的是负数取反加1实际上改变的是
   二进制最低位的1这个性质)2010100)得到 410056.priority_queue<node,vector<node>,cmp>Q;

57.long long+=int  会错  long long+=(long long)int

58.对 list 和 vector 来说,它们的 erase 函数会返回下一个迭代器,因此在遍历时,
   只需要 it = c.erase(it);
   
   对 map 和 set 来说,它们的 erase 函数返回的 void,而在进行 erase 之后,
   当前迭代器会失效,无法再用于获取下一个迭代器。因此需要 erase 之前就获取指向下一个元素的迭代器。
   tmpIt = it;++it; c.erase(tmpIt);  
   利用后缀++操作符的特性(先创建副本,然后再递增迭代器,然后返回副本)上面的三行代码可以简化为一行:
   c.erase(it++); 

59.优化:scanf -> read
         链式前向星,node,priority_queue<node>  
	 ->  vector<pill>,pill,priority_query<pill,vector<pill>,greater<pill> > 
	 注意压入优先队列的pill以dis作为first,id作为second

61.%09d  -> 不足9位在前面补0

62.~0U>>1  ->  INF

63.bitset<100>a   a=a|2 错误 -> a|=2

64.1int)左移超过32位时会出错,所以取一个long long1,同理,在long long型进行位运算的时候
   如果进行32位以上的位操作时,要注意这个问题

65.bitset A(a) 和 A.to_ulong 只限于long ,对于long long要自己写函数

66.multiset erase(10) 是删除所有的10

67.vector<int>a   for(int i=0;i<a.size();i++){...}在删除a[i]后,要使i--
   否则会跳过下一个元素
   
69.矩形a*b的对角线穿过的1*1方格数量为a+b-gcd(a,b)
   立方体a*b*c为a+b+c-gcd(a,b)-gcd(b,c)-gcd(a,c)+gcd(a,b,c)

70.int*int*1llint*int可能会爆精度, ->  1ll*int*int

72.输出浮点数a保留b位 cout<<setiosflags(ios::fixed)<<setprecision(b) << a <<endl;

73.定理1:最小点覆盖数 = 最大匹配数(这些点覆盖所有边)
  定理2:最大独立集 = 顶点数 - 最大匹配数(所有这些点不邻接)
  定理3:最小路径覆盖数 = 顶点数 – 最大匹配数(路径覆盖所有点,一个点只被一条边覆盖)
  KM算法求的是完备匹配,一个点集都匹配,且权和最大
  最小割=最大流
  最大权闭合图的的权=原图中权值为正的点的和 - 最小割(最大流)

74.(D)int+int可能会错,  (D)int+(D)int

76.n个位置选i个且第一个在哪个位置无所谓:C(n,i)*i/n

77.跳出多重循环方法:令多个循环变量变成上限+1

79.和的期望==期望的和

80. C(n,m)=C(n-1,m)+C(n-1,m-1)
	gcd(2^a -1,2^b -1)=2^gcd(a,b) -1
	F(gcd(a,b))==gcd(F(a),F(b))

83.函数内的指针不能用sizeof()

84.所有顶点都落在1*1网格的交叉点上的正多边形只有四边形

85.inline为内联,当函数极其简单时使用

86.__builtin_popcount(i),得出i在二进制中1的数量

88.树形dp可以从上往下维护,也可以先dfs下去,维护好儿子的dp用来维护父亲的dp

90.基于矩阵的搜索(格子与相邻格子的移动),一个点x遍历产生的一圈,圈内的点y对于点x来说的可访问性>y对于圈外点来说的可访问性

91.多个数加上一个定数后的结果,可以用bitset快速维护

94.memset(a,0x3f,sizeof(a))来初始化最大值,最小值为0xC0

95.insert(ls[now],ls[now]=++cnt,l,mid,pos);两个参数都会变成++cnt

96.longlong不能直接赋值为4e18+8,因为这个相当于转成double后存的,double精度上不能达到小数点后18位。
longlong>4e18也不行,因为longlong和double比较时会转换成double,longlong内的数如果是4e18+7就变成4e18了。

97.v.shrink_to_fit() 将vector的多余空间释放

99.Java逆序排序:Collections.sort(V,Collections.reverseOrder());

100.0~n-1的圈每次跳k步,如果k,n互质那么会跳过所有点0 ~n-1;
	每次跳k步和每次跳gcd(n,k)步,遇到的所有点的集合一样

101.ans[--top]=ans[top+1] (本来是ans[top-1]=ans[top],但是不同环境可能变成ans[top-1]=ans[top+1])

102.使用auto来代替复杂的类型声明
	例如multiset<pair<int,int> >::iterator it=S.begin()可以变成auto it=S.begin()

103.函数内部定义局部函数,必须以auto为返回值
	void f1(int p){
	    auto f2=[&](int p){
	        printf("%d\n",p);
	    };
	    f2(p);
	}

104.strcut作为set或map等容器的键值时,需要重载<运算符,且需要稳定排序。
	如果定义了a,b,v,return v<R.v; 其实是错误的。
	应该写成
        return v<R.v || (v==R.v&&a<R.a) || (v==R.v&&a==R.a&&b<R.b);

105.扩栈语句:
	int size = 512 << 20; // 512MB
    char *p = (char*)malloc(size) + size;
    __asm__("movl %0, %%esp\n" :: "r"(p));

106.使用hash的stl,key需要定义hash函数,以pair为例
	struct pair_hash
	{
	    template<class T1, class T2>
	    std::size_t operator() (const std::pair<T1, T2>& p) const
	    {
	        auto h1 = std::hash<T1>{}(p.first);
	        auto h2 = std::hash<T2>{}(p.second);
	        return h1 ^ h2;
	    }
	};
	
	unordered_map<pair<double,double>,int,pair_hash>M;

107.define下,使用#x获取变量或是式子的名字

108.vector在clear后内存不会马上释放,map会

### C语言学习笔记与资料整理 C语言是一种通用的、过程式的计算机编程语言,支持结构化编程、 lexically scoped 语句以及递归函数调用[^1]。以下是关于C语言学习的一些关键点和参考资料: #### 1. 循环结构 C语言提供了多种循环结构以实现重复操作,包括`while`、`do...while`和`for`语句。以下是一个使用`while`循环的示例代码[^1]: ```c #include <stdio.h> int main() { printf("加入比特\n"); int line = 0; while(line <= 20000) { line++; printf("我要继续努力敲代码\n"); } if(line > 20000) printf("好offer\n"); return 0; } ``` #### 2. 随机数生成与用户交互 在C语言中,可以通过`rand()`函数生成随机数,并结合`time()`函数设置随机种子以确保每次运行时生成不同的随机数。以下是一个猜数字游戏的示例代码[^2]: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { srand(time(0)); int number = rand() % 100 + 1; // 生成1到100之间的随机数 int count = 0; int a = 0; printf("我已经想好了一个1-100之间的数\n"); do { printf("请猜数:"); scanf("%d", &a); count++; if (a > number) { printf("你猜的数大了\n"); } else if (a < number) { printf("你猜的数小了\n"); } } while (a != number); printf("太棒了,你用了%d次就猜对了答案\n", count); return 0; } ``` #### 3. 整数逆序求解 对于整数逆序问题,可以利用`%`运算符获取个位数,`/`运算符去掉个位数,逐步构建逆序结果。以下是一个整数逆序的示例代码[^2]: ```c #include <stdio.h> int main() { int x; scanf("%d", &x); int digit; int ret = 0; while (x > 0) { digit = x % 10; ret = ret * 10 + digit; printf("x = %d, ret = %d, digit = %d\n", x, ret, digit); x /= 10; } printf("%d", ret); return 0; } ``` #### 4. 常见错误及调试技巧 在C语言编程过程中,常见的错误包括数组越界访问、指针使用不当、内存泄漏等。为避免这些问题,建议养成良好的编程习惯,例如初始化变量、检查边界条件、使用调试工具(如`gdb`)等。 #### 5. 学习资源推荐 - **书籍**:《C程序设计语言》(The C Programming Language),由Brian W. Kernighan和Dennis M. Ritchie编写。 - **在线教程**:菜鸟教程(https://www.runoob.com/cprogramming/index.html)、GeeksforGeeks(https://www.geeksforgeeks.org/c-programming-language/)。 - **实践平台**:LeetCode、Codeforces、HackerRank等提供丰富的C语言练习题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值