“Hello world”
#include<stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
一些新手常见错误
- 没弄清赋值关系
#include<stdio.h>
int main()
{
int a,b,c;
scanf("%d%d",&a,&b);
c=a+b;
c=a-b;
c=a*b;
c=a/b;
c=a%b;
printf("%d+%d=%d\n%d-%d=%d\n%d*%d=%d\n%d/%d=3\n%d%%d=%d\n",a,b,c,a,b,c,a,b,c,a,b,c,a,b,c);
return 0;
}
#include <stdio.h>
int main()
{
int a,b;
int c;
scanf("%d%d",&a,&b);
c=a+b;
printf("%d+%d=%d\n",a,b,c);
c=a-b;
printf("%d-%d=%d\n",a,b,c);
c=a*b;
printf("%d*%d=%d\n",a,b,c);
c=a/b;
printf("%d/%d=%d\n",a,b,c);
c=a%b;
printf("%d%%%d=%d\n",a,b,c);
return 0;
}
- 逻辑运算没弄清
#include<stdio.h>
int main()
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(a>b+c||b>a+c||c>a+b)
printf("non-triangle.\n");
else
if(a==b&&b==c)
printf("equilateral triangle.\n");
else
if ((a==b&&a!=c)||(a==c&&a!=b)||(b==c&&b!=a) )
printf("isoceles triangle.\n");
else
printf("triangle.\n");
return 0;
}
/* 很容易直接翻译数学关系 从而弄错逻辑运算 如何 a==b==c*/
-不熟悉位运算和非10进制
if ( a=0xA | a >12 )
if ( 011&10==a ) printf (”%d!\n”,a);
else printf (”Right!%d\n”,a);
else printf (”Wrong!%d\n”,a);
011&010 == 1001&1010=1000=0x08
simply printf()
字符
类比Hello World
计算 calculation
#include <stdio.h>
int main()
{
printf("23+43=%d\n", 23+43);#%d代替后面的数值。
return 0;
}
情景运用
- 超市购物
#include <stdio.h>
int main()
{
int price = 0;
printf("请输入金额(元):");
scanf("%d", &price);
int change = 100 - price;
printf("找您%d元。\n", change);
return 0;
}
- 输出整型变量x对应的十进制、八进制和十六进制形式
方法一:
直接使用控制字符串
%o 八进制
%X 十六进制
方法二:
函数 char *itoa(int value, char *string, int radix)
返回值类型char
参数value 待转换的数字
参数string 转换后存储到string中
参数radix 转换到几进制
定义在 stdlib.h
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int main()
{
int userinput;
printf("Please enter a integer.\n");
scanf("%d",&userinput);
char octal[MAX],hex[MAX];
itoa(userinput,octal,8);
itoa(userinput,hex,16);
printf("Octal and Hex of the integer %d that you entered is %s and %s.\n",userinput,octal,hex);
return 0;
}
————————————————
版权声明:本文为CSDN博主「Cytosine」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Cytosine/article/details/59189577
一些特殊公式
- 吉姆拉尔森公式
优化后的公式 : W= (d+2m+3(m+1)/5+y+y/4-y/100+y/400+1)%7
=(d-1+y+y/4-y/100+y/400+2(m+1)+3(m+1)/5)%7
公式原理
“计算”
变量
%c 字符 %s 字符串 %d 小数 &d 整数
- 变量自增自减运算
i++ 先使用变量的值 再加一++i 先加一 再使用变量的值
同上 i-- --i - 复合运算符
- List item
如何定义变量
int char double float
关于getchar
字符输入: ch=getchar()
字符输出: putchar(ch)
//结合循环可实现字符串输入输出
关于scanf函数
1.scanf(“%d”,&A)
%3d 从头开始取三位 小数点算一位
%.3d 小数点后三位
%3.2d 小数点前三位,后两位
利用getchar()进行特殊的读取
eg:读取未知长度的数字;
scanf(),getchar()灵活结合。
其中一些details
1.sqrt(x) 求平方根
2.整数相除结果只取整数部分,小数丢弃。
3.sanf()不可以指定数据格式%m.n 会造成语言系统不理解 如:%4.2f
4.余数的符号取决于被除数
5.求余对象必须是整型!
6.(int)x 强制取整
7.c语言没有专门的逻辑字符 一般用 0 1
8.c语言中单引号里放字符 双引号里放字符串
9.或运算如果前面已经为真 后面就不会算了
10 已知int i=1; 执行语句while (i++<4) ;后,变量i的值为 答案:(5)
理解i++。
10.左对齐
在打印数字宽度前面加一个“-”,假设数字宽度为2,如果要打印的位数小于2,则在后面补足空格,如果要打印的位数大于2,则打印所有的数字,不会截断。
右对齐
在%和d之间加上数字宽度
假设数字宽度为 2,如果要打印的位数小于 2,左边补足空格;如果要打印的位数大于 2,则打印所有的数字,不会截断。
- 计算机计算规则
已知:char c=‘A’; int i = 1, j;。执行语句 j = !c&&i++; 后,i 和 j 的值是:
答:1和0。
解析:c为真 !c则为假 &&后就不会执行了
if(!k)不等价与 if(k!=!0) 因为!0为1 后者意思为k!=1 显然与前者不同
11. 进制的表示
一、八进制由 0~7 八个数字组成,使用时必须以0开头(注意是数字 0,不是字母 o),例如:
//合法的八进制数
int a = 015; //换算成十进制为 13
int b = -0101; //换算成十进制为 -65
int c = 0177777; //换算成十进制为 65535
//非法的八进制
int m = 256; //无前缀 0,相当于十进制
int n = 03A2; //A不是有效的八进制数字
二、十六进制由数字 0~9、字母 A~F 或 a~f(不区分大小写)组成,使用时必须以0x或0X(不区分大小写)开头,例如:
//合法的十六进制int a = 0X2A; //换算成十进制为 42
int b = -0XA0; //换算成十进制为 -160
int c = 0xffff; //换算成十进制为 65535
//非法的十六进制
int m = 5A; //没有前缀 0X,是一个无效数字
int n = 0X3H; //H不是有效的十六进制数字
一些问题解决
#include <stdio.h>
main()
{
int a;
char b;
float c;
printf("Please input an integer:");
scanf("%d", &a);
printf("integer: %d\n", a);
printf("Please input a character:");
getchar(); /*将存于缓冲区中的回车字符读入,避免被后面的变量作为有效字符读入*/
scanf("%c", &b);
printf("character: %c\n", b);
printf("Please input a float number:");
scanf("%f", &c);
printf("float: %f\n", c)
上一行的回车符会造成被后面当成变量输入 所以需要getchar()
常见错误:
–scanf(“%d,%f\n”,&a,&b);
–scanf(“%d,%f”,a,b);
–scanf(“%7.2f”,&a);
scanf(“%d%c%d”,a,b,c)这种情况下输入时不能打空格。
- 4.double
double精度比float更高
double a;
scanf(“%f”,&a); //应用scanf(“%lf”,&a);
执行上面语句时,发现double类型的输入不能使用%f进行输入,得用%lf才能正常得到a的值。
而在输出double类型时却可以用%f,这是因为printf(“%f”,a);在执行时C自动将float型的参数转换成double型!!!!
故double型的输入输出形式如下:
double a;
scanf(“%lf”,&a);
printf(“%f”,a);
数据类型
- 隐式转换
精度低的向精度高的转换
- 强制转换
(数据类型)x
表达式
(条件)?语句一:语句二 ?仅高于赋值运算符
为真语句一赋值给x 否则语句二赋值给x
运算符优先级
&&与 ||或 !非
-逗号运算符,
a=(xxx,xxx,xxx);其值为最后一个表达式的值
- &取地址符 取指定变量的地址
- 取负运算符
将正数变负数 级别高 - ()通常用于改变运算次序
- []下标运算符 通常用于数组
已知int i,a; 执行语句"i=(a=23,a5),a+6;"后,变量i的值是 。 ( 30 )
赋值运算优先级高于逗号运算
if ( a=0xA | a >12 )
if ( 011&10==a ) printf (”%d!\n”,a);
else printf (”Right!%d\n”,a);
else printf (”Wrong!%d\n”,a);
① a=014时
第一个数为0,说明这个数是八进制
if(a=0xA | a>12):按照“运算符优先级”,先算a>12吗?八进制14等于十进制12,所以a不大于12。结果为0
第二步:0xA | 0 :十六进制A,按位或 0,结果肯定还是十六进制A了,任何数按位或0的话,等于任何数。所以这个if为真
第三步:if(011&10 == a):这里还是要考虑运算符的优先级,的优先级比&的优先级高,所以10a吗? 第二步可以看到,a的值已经变成0xA了,十六进制A等于十进制10,所以10a为真。真就是1
第四步:011&1 为真吗? 八进制011等于二进制1001,十进制1等于二进制0001,所以1001&0001 按位与后为0001 结果为真,所以执行printf(“%d!\n”, a)
第五步:第二步已经把a改变了,所以a等于10,结果10!
②a=0x14时
0x为十六进制,十六进制14等于十进制20,等于二进制10100
解答:
1、还是优先级的问题,20大于12吗?yes,yes为真为1
2、十六进制A等于二进制1010
3、1010 | 0001 结果为1011等于十进制11,所以这个时候a=11
4、if(011&10a)
5、注意优先级 10==11吗?假,为0
6、011&0 八进制11,转化为二进制为1001&0000结果0000 假
7、第6的时候为假,所以执行else,结果为Right!11
结束!!
注意问题:
1、==的优先级大于&
2、>的优先级大于| 大于=
3、c语言是按顺序执行的,a=0xA | 先运算0xA,因为0xA后面有一个 | ,所以先执行| ,执行0xA | a,但是a后面有一个>,>的优先级又比|高,所以先执行>, 执行a>12,12后面没什么东西了,所以就先执行a>12 了。
4、考点:1、按顺序执行 2、运算符优先级
a=1+2+34 等于什么呢?按照数学的话,一眼看出来先执行34,但这里是C语言
按顺序执行,先执行1+2,2后面是+号,优先级一样,所以先执行1+2=3
3+34 — 3+3 但是3后面,所以这里就先执行*了,这时3+12
所以结果等于15
交换变量
转换
判断与循环
while语句
while(表达式)
for循环
新思路:双变量设置循环条件
switch
注意每一个case 中的 break
-case后每个常量必须各不相同。
-每个case后可执行语句可大于1,不必加{ }。
Demo1:
#include <stdio.h>
main ( )
{ int x=1, y=0, a=0, b=0;
switch ( x )
{ case 1: switch ( y )
{ case 0: a++; break;
case 1: b++; break;
}
case 2: a++; b++;
break;
}
printf ("a=%d,b=%d\n", a, b );
}
输出:a=2 b=1 易错:a=1 b=0
case1 后面没有break。
位运算
& 与
| 或
^异或
~ 求反 b=~a
x>>n x<<n移位号
转移语句
break
break语句的功能
1.在 switch 语句中结束 case 子句,使控制转到switch语句之外。
2.在循环语句的循环体中使用,结束循环过程,使控制转移到整个循环语句之外的下一条语句处。
例C6_6101.C:求 555555 的约数中最大的三位数是多少?
main( )
{ int j; long n;
printf(“Please input number:”);
scanf(“%ld”, &n);
/* 所求约数取值范围999~100,j从大到小 /
for (j=999; j>=100; j–)
if ( n%j==0 ) / 若能整除j,则j是约数 /
{ printf(”3 digits in %ld=%d\n”, n, j );
break; / 控制退出循环 */
}
}
continue
continue语句的功能
continue语句仅能在循环语句中使用.
它的作用不是结束循环,而是开始一次新的循环。
对于for语句,将控制转到执行表达式3和条件测试部分;
对于while和do-while语句,将控制转到条件测试部分;
从逻辑上讲,适当改变程序的结构就可以不需要使用continue语句。
goto
goto语句的功能
1、将控制转移到标号所指定的语句处继续执行。
2、标号的唯一功能就是作为goto语句的目标。标号的作用域是它所在的整个函数。
goto语句的使用说明
在C语言中,goto 语句并不是必不可少的,使用 goto 语句的地方都可以用C的其它控制流程语句改写。
#include <stdio.h>
main( )
{ int a, b, c, d, i;
for (a=1; a<=5; ++a) /* 在a的范围内穷举 */
for (d=1; d<=3; ++d) /* 在d的范围内穷举 */
{ b=a+(a+d)+(a+2*d)+(a+3*d); /* 前四项的和 */
c=a*(a+d)*(a+2*d)*(a+3*d); /* 前四项的积 */
if ( b==26 && c==880 ) /* 若满足条件 */
goto out; /* 退出二重循环 */
}
out: /* 语句标号 */
for (i=0; i<=20; ++i) /* 输出运行结果 */
printf("%d,", a+i*d);
}
return(难理解)
retunrn 语句格式
格式一:return;
格式二:return (表达式);
return 语句的功能
1.return语句使程序从被调用函数中返回到调用函数的调用处继续运行。
2.如果return后跟一表达式,则该表达式的值会从被调用函数中带回到调用它的函数,称为返回值。
数组
数组:一组具有相同数据类型的数据的有序的集合。
- 数组元素:构成数组的数据。数组中的每一个数组
元素具有相同的名称,不同的下标,可以作为单个变
量使用,所以也称为下标变量。
• 数组的下标:是数组元素的位置的一个索引或指示。
• 数组的维数:数组元素下标的个数。
一维数组
一维数组的定义方法为:
类型说明符 数组名[常量表达式];
一维数组通常和一重循环相配合,对数组
元素进行处理。
!!下标从0开始
赋值
例: int a[4]={1, 3, 5}
则a[0]=1,a[1]=3,a[2]=5,a[3]=0
int a[ ]={1, 3, 5}
相当于 int a[3]={1,3, 5}
二维数组
基本的初始化方法
如何给开头一个元素赋值输出
二维数组的几种输出方式
同时熟悉字符数组的赋值及输出以及一些特殊函数。
例题:
#include <string.h>
main()
{char words[5][15]={{'\0'},{'\0'},{'\0'},{'\0'},{'\0'}},temp[15]={0};
int i,j,k;
scanf("%s",words[0]);
for (i=1;i<5;i++)
{ scanf("%s",temp);
//strcpy(words[i],temp);
j=i-1;
while(strcmp(temp,words[j])<0)
{
strcpy(words[j+1],words[j]);
j--;
}
strcpy(words[j+1],temp);
}
for (i=0;i<5;i++)
printf("%s\n",words[i]);
printf("\n");
}
指针
指针变量
说明方式: 数据类型 *变量名;
char *p;int *a;
指针运算符
& 取变量的地址 14
*取指针变量所指向的内容 14
p=&x;将指针指向x
*p=x无法取值
指针与函数的关系
features:
1.函数的返回值为指针。
2.通过参数在函数之间传递变量地址,既在函数之间传递指向变量的指针。
3.指针指向的对象使函数,称为函数指针。
函数之间传递变量的地址
在函数间传递变量地址时,变量的地址在调用函数时要作为实际参数,被调用函数时要作为实际参数,被调用函数使用指针变量作为形式参数接收传递的地址。
形式参数:int *p;
实际参数:&x;
注意:实参的数据类型要与作为形参的指针所指的对象的数据类型一致。
#include<stdio.h>
void main()
{
int a,b,c;
scanf("%d%d",&a,&b);
c=plus(&a,&b);
printf("A+B=%d',c);
}
plus(int *px,int *py)
{
return (*px+*py);
}
指向函数的指针
- 定义函数指针
类型标识符(* 变量名)() - 给函数指针变量赋值
函数指针变量=函数名 - 通过指针变量调用函数
(* 函数指针变量)(实际参数)
#include<stdio.h>
void main()
{
int max(int,int);
int (* pf)();
int a,b,c;
pf=max;
scanf(" ");
c=(* pf)(a,b);
..........
}
在函数的形参中使用指向函数的指针
形参是函数指针时,实参应为函数名,即函数在内存中的可执行代码的首地址(入口)
算法
贪心算法
贪心算法(greedy algorithm [8] ,又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解 [1] 。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择 [1] 。
思路:
贪心算法一般按如下步骤进行: [2]
①建立数学模型来描述问题 [2] 。
②把求解的问题分成若干个子问题 [2] 。
③对每个子问题求解,得到子问题的局部最优解 [2] 。
④把子问题的解局部最优解合成原来解问题的一个解 [2] 。
贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。贪心算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,省去了为找最优解要穷尽所有可能而必须耗费的大量时间。贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解。虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪心算法不要回溯 [2] 。
使用条件:
利用贪心法求解的问题应具备如下2个特征 [4] 。
1、贪心选择性质
一个问题的整体最优解可通过一系列局部的最优解的选择达到,并且每次的选择可以依赖以前作出的选择,但不依赖于后面要作出的选择。这就是贪心选择性质。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解 [4] 。
2、最优子结构性质
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心法求解的关键所在。在实际应用中,至于什么问题具有什么样的贪心选择性质是不确定的,需要具体问题具体分析 [4] 。
解题策略:
贪心算法不从整体最优上加以考虑,所做出的仅是在某种意义上的局部最优选择。使用贪心策略要注意局部最优与全局最优的关系,选择当前的局部最优并不一定能推导出问题的全局最优。贪心策略解题需要解决以下两个问题: [5]
1、该问题是否适合使用贪心策略求解,也就是该问题是否具有贪心选择性质 [5] ;
2、制定贪心策略,以达到问题的最优解或较优解 [5] 。
要确定一个问题是否适合用贪心算法求解,必须证明每一步所作的贪心选择最终导致问题的整体最优解。证明的大致过程为:首先考察问题的一个整体最优解,并证明可修改这个最优解,使其以贪心选择开始,做了贪心选择后,原问题简化为规模更小的类似子问题。然后用数学归纳法证明通过每一步做贪心选择,最终可得到问题的整体最优解 [5] 。
存在问题:
贪心算法也存在如下问题: [6]
1、不能保证解是最佳的。因为贪心算法总是从局部出发,并没从整体考虑 [6] ;
2、贪心算法一般用来解决求最大或最小解 [6] ;
3、贪心算法只能确定某些问题的可行性范围 [6] 。
参考:摘桃子(小学期)
高斯消元法
深度优先搜索法
基本概念
深度优先搜索算法(Depth First Search,简称DFS):一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。
算法思想
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
基本模板:
int check(参数)
{
if(满足条件)
return 1;
return 0;
}
void dfs(int step)
{
判断边界
{
相应操作
}
尝试每一种可能
{
满足check条件
标记
继续下一步dfs(step+1)
恢复初始状态(回溯的时候要用到)
}
}
问题示例
- 解谜游戏
- Description
小张是一个密室逃脱爱好者,在密室逃脱的游戏中,你需要解开一系列谜题最终拿到出门的密码。现在小张需要打开一个藏有线索的箱子,但箱子上有下图所示的密码锁。
每个点是一个按钮,每个按钮里面有一个小灯。如上图,红色代表灯亮,白色代表灯灭。每当按下按钮,此按钮的灯以及其上下左右四个方向按钮的灯状态会改变(如果原来灯亮则灯灭,如果原来灯灭则灯亮)。如果小张通过按按钮将灯全部熄灭则能可以打开箱子。
对于这个密码锁,我们可以先按下左上角的按钮,密码锁状态变为下图。
再按下右下角的按钮,密码锁状态变为下图。
最后按下中间的按钮,灯全部熄灭。
现在小张给你一些密码锁的状态,请你告诉他最少按几次按钮能够把灯全部熄灭。
Input
第一行两个整数 n,m(1 \leq n,m \leq 16 ) 。
接下来 n 行,每行一个长度为 m 的01字符串,0表示灯初始状态灭,1表示灯初始状态亮。
Output
一行一个整数,表示最少按几次按钮可以把灯全部熄灭。
Notes
第一个样例见题目描述,第二个样例按左上和右下两个按钮。
测试用例保证一定有解。
测试输入 期待的输出 时间限制 内存限制 额外进程
测试用例 1 以文本方式显示
3 3↵
100↵
010↵
001↵
以文本方式显示
3↵
测试用例 2 以文本方式显示
2 3↵
111↵
111↵
以文本方式显示
2↵ANSWER:
(后续对函数进行分析)
#include <cstdio>
#define MAX_LEN 17
int n, m, a[MAX_LEN][MAX_LEN];
int cur[MAX_LEN][MAX_LEN]; //存储处理完第一排后的状态
int ans = 256; //存储答案:最小步骤。初始为最大值256步
/* 将p位置上的整数做一个反(异或)操作:
* 1变成0, 0变成1 */
void change(int *p) {
if (*p == 1)
*p = 0;
else
*p = 1;
}
/* 设定将a[i][j]处按下所产生的反应
* 注意:a数组根据传递的地址而定 */
void push(int a[][MAX_LEN], int i, int j) {
change(&a[i][j]);
if (i - 1 >= 0)
change(&a[i - 1][j]);
if (j - 1 >= 0)
change(&a[i][j - 1]);
if (i + 1 < n)
change(&a[i + 1][j]);
if (j + 1 < m)
change(&a[i][j + 1]);
}
/* 当第一排的灯被弄完后,把灯的状态复制到cur数组中
* 便于后面的计数与操作,不会影响到原数组a */
void getCur() {
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cur[i][j] = a[i][j];
}
/* 当第一排的灯被弄完后
* 逐排操作,计算是否能够全部灭完
* 如果不可以:返回-1;否则:返回操作次数 */
int calc() {
getCur();
int step = 0;
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < m; j++) {
if (cur[i][j] == 1) {
step++;
push(cur, i + 1, j);
}
}
for (int i = 0; i < m; i++)
if (cur[n - 1][i] == 1)
return -1;
return step;
}
/* 深度优先搜索,枚举第一排按键的所有按法
* step: 当前讨论第1排第step + 1个按键
* count: step之前按键一共被操作了的次数和 */
void dfs(int step, int count) {
// 深度优先搜索的终点:讨论完第一排最后一个按键了
// 已经按照一种方式将第一排操作完成
if (step == m) {
int t = calc(); //计算该基础上熄灭所有的灯需要的步数
if (t == -1) //无解
return;
if (t + count < ans) //有解,更新最小值
ans = t + count;
return;
}
push(a, 0, step); //按下第一排第step-1个按键
dfs(step + 1, count + 1);
push(a, 0, step); //再次按下(相当于还原)第一排第step-1个按键
dfs(step + 1, count);
}
int main() {
scanf("%d%d\n", &n, &m); //一定要加上\n,作用:吸去换行符
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
char c;
c = getchar();
a[i][j] = c - '0'; //将字符转化为整数考虑
}
getchar(); //吸去换行符
}
dfs(0, 0);
printf("%d\n", ans);
}
————————————————
版权声明:本文为CSDN博主「贝贝今天AC了吗」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43787043/article/details/108506008
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。