新手 起飞

新手杂干

试水

1.在有标记的字符串中取数:cin 串,if,cin 数

  1. 球体积,4 / 3 荒谬!

  2.                                        switch (c)
              {
     	case 10 : case 9 : cout << 'A' << endl; break;
     	case 8 : cout << 'B' << endl; break;
     	case 7 : cout << 'C' << endl; break;
     	case 6 : cout << 'D' << endl; break;	
     	case 5 : case 4 : case 3 : case 2 : case 1 : case 0 :
     		cout << 'E' << endl; break;
     	default : cout << "Score is error !" << endl;	
              }
    
  3. 时刻注意除法中的整形陷阱!即使左边是double,右边也有可能,,,,

  4. 注意换行与空格的时机分布

  5. 事先赋值,未知范围,求最大,可用INT_MAX,以待之,最小 ,用-INT_MAX!!

  6. 自己得出两个数组比较时,可能第二个数组不需要设(数字不需要保存);而且第二个数组也许不用全求出来,可以边求边比较,直至完成

8.pow浪费时间,尤其是在循环里面,也许可以借循环之便利,22*2!

9.一个函数用两次,定义两个函数-----不一样,选取!

  1. 有些不必要的可以不存,可以边算边比

  2. 全局变量隨递归进入下一层,不可用其恢复状态

  3. 用求余来表示平移时,需数组从0开始,因为无n

  4. 利用中间结果,记忆,避免重复,或者及时返回

14.环,或者平移,皆可用求余运算

15.去除,或者消灭,可以用另外的数组标记,这样就不用真刀真枪的修改,恢复时改标记即可

16.注意,前面有递归,则是全递归完成后才下一步----所以不用将标记函数设成参数,设成全局变量即可,回来之后再恢复,然后循环

17.永远不要忘记tall可能小于其他数的教训!!!要再判断,三个小时啊啊啊啊(竟然忘记了什么意思,,大概是不要默认最大,细心再比较一次来保证吧)

  1. 主函数中也用一个循环,为入口,多次递归,循环内留下最大(有点自己写的初级小天的意思了)

19.计数方法总数时,可用int型函数,i==1时,(完成时),返回一,,其余各层,写way+=f(n-1)(有汇总之意);最后的最后,return way;(此为通道)

20.for(int k = start; k != end; k = (k+1)%N) 如此循环分点,后面分段。(求余是因为14,原为环,主函数中断开了)

  1. 将运算符与数字分开,存为两个数组,但仍有序,可计算

  2. 动态规划,不止稀释,还能,区域最大值。----利用循环与比较,不过循环是从小到大,而递归是从大到小,且全遍历之后再比较

23.因为不同的操作,在尝试不同的处理,会有重复的操作,因此利用数组保存已经比较过的值-----记忆(后路已遍历)

24.double k3 = macth(p + 1, q + 1); //修改其中一个串的首字母
f[p][q] = min(k1, min(k2, k3)) + 1;
return f[p][q];
如此对待返回值,将其视作一个已知的数,信手拈来,神乎其技

25.避免超时:
1. 在求最大最小值的情况,该值设为全局变量,每个函数都能看到,不需要传递。
2. 满足条件或者肯定不满足条件及时终止递归。
3. 记忆搜索是动态规划思想的体现。

26.先扫描“|”,相当于与优先权让给“&” ------- 先扫描,则无优先权

  1. min,及,max 函数头文件是《algorithm》

  2. min,及,max 是保留xx,不能以此二者命名变量

29.函数参数改变时,不要轻易使用++!!!!!因为,或者之前,或者之后,才会改!!(返回之前后!!!全部!!),,,所以应用x+1!!!!老老实实!!!

  1. 一次调用完成一层循环,第一次调用是最外层循环,最后调用是最内层循环。
    ? 程序的结束是第一个递归函数的循环全部结束
    ? 递归函数的结束是本函数内的循环全部结束
    ? 每个函数中的循环结束,return到上一次调用的循环体中

  2. 写此类函数大致需要:

    1. 结束条件,最外层循环结束,n==0
    2. 写出循环的主体
    3. 在循环体内递归调用
  3.                                            通过比较《滑雪》问题,有感
    

    先从根本上分析一下,似乎现在比较习惯于设全局变量,然后通过递归函数分层对它的改变或构造来得到所求。而不善于利用int之类的利用函数的返回值(老是设void的函数);
    其次,同样是记忆,递归,但我好像没有用“回溯”?我的“记忆”单纯是为了防止多走路,而没有像代奶奶一样,将记忆利用的淋漓尽致,直接不再走路。
    每次,都已经探索尽了所有可能,那为什么不比较一下,利用的充分一点?经验不足啊啊啊啊啊啊

  4. if (----)
    { if(----)
    { 与 If (------&&-----)不同!!!不不不,也许相同,不过有一点点不一样,有时里面的if可能会溢出,不不不,应该一样
    }
    }

  5. 震惊!! (见滑雪)
    m设全局变量,然后再在函数中初始化,与 ,在相同位置设局部变量,定义时初始化,,,不一样!!!
    因为:尤其是递归时,若全局变量,则最后使用的m是最后一次的函数决定的(好像不是),但!在比较时有影响,是的!!但!!!而局部变量时,相当于分层利用,比较友好。
    影响:s = way (x + dx[i], y + dy); if (s > m) m = s; 全局变量的初始化在前,可以控制,递归的去(虽然好像此时与m无关无用),不能控制递归的回,----返回时,m只能一次比一次大
    了,否则,m不变化 --------------- 对于不同层次变化的量,且层次间无关的量,还是设局部好

  6. char a[9][9];
    

    for (int i = 1; i <= 6; i++) 实践证明,这样把一个表达式分数字与运算符输出,是可以的
    {
    cin >> a[i];
    }
    for (int i = 1; i <= 6; i++)
    {
    if (a[i][0] != ‘*’ && a[i][0] != ‘+’) 注意:这里加上【0】,只比较首位就可以了,如果不加零,好像是指针(输入,输出时可以,比较时不行了)
    cout << atof(a[i]); 注意:头文件是 《cstdlib》,作用:把一个字符串 转变成浮点数
    else cout << a[i];
    }

  7. 对于while(cin》》)之类的,本地不会停止,而且如果递归/操作在while外面,就会比较尴尬,所以可以自己设停止条件,比如输入#时。有意思的是,对网格也没有影响。

  8. 处理算数表达式时,可以通过输入的同时判断,将数字存入另一个数组;
    自己的聪明才智,认为“栈”可以用平移,至相近处,然后操作;(猜想,可以构造不同的计数变量,+±-?maybe)( 2019/01/10 23:18 看不懂了)

38.堆栈,用于有顺序的判断处理
() 相当于 \0 表示一个块 的结束,相当于分块,以及,逆向。两个栈,弹栈,压栈(top的改变),运算

  1. 数组本质就是指针(p=a),形式也一样,也不对,p可以动,a永远是a

  2. a=5 表达式值为 5 (等于号右式) 用于while 中

  3. int 一个数,》》3.4,输出3;保留2位, 输出3; 类型,代表了潜力,且尽量最短
    3,输出3;保留2位, 输出3;
    double 一个数,》》3.4,输出3.4;保留2位, 输出3.40;
    3,输出3;保留2位, 输出3.00;

  4. (int)–,强制转换,只是暂时转换,再输出依然原样。

  5. 不要自以为样例很大 或许只有一个,,,,所以保险,不要随意,,,不能直接默许len = word【1】

44 . 样例中临界大数!!判断时,用 a-b》b,,,,不用2*a》b!!!

  1. 二维数组 a【1100】【1110】就溢出?? 我勒个去

  2. 推到重来,决不能苟延残喘,姑息于它!

  3. for (int i = 1; i < num; i++) // 括号按长度排序!!!! 两个数组对应 !!!如此排序,如此对应。好处:内容不乱。另:似乎冒泡更快?对于我自己的方法+指针,,,,所以,以后用冒泡吧
    for (int j = num; j > i; j–)
    if (prt[j - 1] - plf[j - 1] > prt[j] - plf[j]) ***********!!!!!!!
    {
    t = prt[j - 1];
    prt[j - 1] = prt[j];
    prt[j] = t;
    t = plf[j - 1];
    plf[j - 1] = plf[j];
    plf[j] = t;
    }

48.字符转换成 数字时,整数正序,小数倒序,因为不断除以10

  1. 有些时候不用递归,,,

  2. 有些时候不记忆,且不能记忆(情况条件不同时)

  3. 回溯时,不可毁掉前面的标记(一般循环回溯,不能毁掉i-1的标记)
    例如:biao[i][j]++(不用biao[i][j] = 1)
    biao[i][j]–(不用biao[i][j] = 0)

  4. 对角线表示方法!!!!


53. 2018/12/08 12:30
cout << setfill(‘0’)可以设置填充字符为’0’;
设完之后记得调用setfill(’ ')设回空格,否则会影响后续输出。

  1. double x = 35.54767;
    cout << x << endl; //缺省输出6位,四舍五入
    cout << setprecision(7) << x << endl; //指定输出7位
    cout << fixed; //接下来按固定小数点输出
    cout << x << endl; //前面的setprecison(7)代表小数点后面输出7位
    cout << setprecision(0) << x << endl; //小数点后面0位
    cout << setprecision(1) << x << endl; //小数点后面1位
    cout << setprecision(2) << x << endl;
    cout << setprecision(3) << x << endl;
    cout << resetiosflags(ios::fixed) << endl; //取消定点
    cout << x << endl; //最后的设定有效

35.5477
35.54767
35.5476700
36
35.5
35.55
35.548
35.5
语法: cout 输出浮点数时,最后一位四舍五入

  1. //格式控制样例
    int main()
    {
    double x = 35.54767;
    cout << setw(10) << x << endl; //设置输出占10位,数值本身6位,
    //小数点1位,补三个空格。
    cout << setw(10) << setprecision(7) << x << endl; //比前上一句多 //输出1位数值
    cout << fixed; //按定点输出
    cout << x << endl; //小数点后面输出7位,setw(n)只控制一次
    cout << setprecision(0) << x << endl; //小数点后面0位
    cout << setprecision(1) << x << endl; //小数点后面1位
    cout << setprecision(2) << x << endl;
    cout << setw(10) << setprecision(3) << x << endl; //需要不三个空格
    cout << resetiosflags(ios::fixed); //取消定点
    cout << x << endl; //恢复setprecision(3)

___35.5477
__35.54767
35.5476700
36

35.5
35.55
____35.548
35.5

56, 不加任何输出控制,cout一个浮点数,只输出6位。
例:cout << 22.0/7; // 3.14286
cout<setprecision(n);单独使用,设置整个数据的 长度,不包括小数点
cout<< setprecision(3)<<22.0/7 << endl;//3.14
reset和set采用同样的参数,就是取消
 setw(n)和setprecision(n)的区别:
 前者包括小数点和空格,(对额外的形式的规定==美化)另:可与setfill结合使用,见 53
后者只包括数据位数(对数据本身精度的规定)

  1. 感觉硬币面值题与上台阶题不一样,虽然都是总数+单位方法。但似乎一个是组合,一个是排列。(但“程序园”上说一样,为什么?)

58,
2018/12/08 15:28
// 1. 当前行不放棋子,棋子数不变,列加1
int result = Find(left, col + 1); //
2. 当前行放棋子 for (int i = 0; i < n; i ++)
if (!row[i] && board[i][col]) // 计算在第i列放棋子的方案数
{
row[i] = true;
result += Find(left - 1, col + 1);
row[i] = false; //回溯
}
return result;

不放时,亦是一种方案; += 用的极好!
(要是我自己做,就会在最后方设一个c++,用来计成功数)

59, 分割问题,递归时形参:end与start

  1. 有时可进行返回值之间的比较,但有时为了减少重复调用同一层次的函数,可以另p = f【】(如同令a = sqrt()),或为了避免两次调用带来的影响

    重新开始:
    

二维数组下标,或者以为数组下标及其值的功能:可类似于指针,有指向性,或者类似于区间,可用来表示分段。(而不仅仅是行列)

要不要回溯(释放约束条件)?
如果在搜索的过程中,通过标记(约束)对搜索进行有条件 的导向,在回溯的过程中要释放约束。
此题要找最长的路径,因为走过的地方需要重走,因此回溯 时要释放条件。
对照迷宫问题,只要有一条能走到终点,因此不需要回溯, 直接返回。
避免超时: 在求最大最小值的情况,该值设为全局变量,每个函数都能 看到,不需要传递。 满足条件或者肯定不满足条件及时终止递归。 记忆搜索是动态规划思想的体现。
或许可以在循环内判断是否结束递归——此时,整个函数只有一个循环。

for (int i = 0; i <= m / k; i++)
{
if (k == 5)
{
mon (2, i, b, c, m - i * k);
}
if (k == 2)
{
mon (1, a, i, c, m - i * k);
}
if (k == 1)
{
cout << setfill (‘0’) << setw (3) << ++ci << setfill (’ ') << setw (12) << m << setw (12) << b << setw (12) << a << endl;
return;
}
}

比较神奇的递归(真正知道下一个数是什么),噢噢噢噢,看懂了,他遍历了所有可能的第一种钱,然后进入下一个,厉害啊。
此外,好像与循环没有区别

void mon (int a, int b, int c, int m)
{
if (m < 0)
return;
if (m == 0)
{
if (jiyi[a][b][c] == 1)
return;
}
if (m == 0)
{
jiyi[a][b][c] = 1;
cout << setfill (‘0’) << setw (3) << ++ci << setfill (’ ') << setw (12) << a << setw (12) << b << setw (12) << c << endl;
}
mon (a + 1, b, c, m - 1);
mon (a, b + 1, c, m - 2);
mon (a , b, c + 1, m - 5);
}

反例:复杂度变成了指数,原来是幂。因为太多明明知道无用的步骤。而且5的递增不等于1的递减。
第 2 行就是宏定义,在编译时,第 3、4 行的会被替换成,注意第 2 行末尾没有分号 的意思是告诉编译器,在程序中所有出现的都替换成 我们经常会遇到多个数组应该声明成 相同长度的情况,这种时候用宏定义就比每个位置都写一个 方便了,之后一旦需要修改数 组长度直接改宏定义的部分就好了.( # define maxn 105 ) (无等于号,无分号) 后面可以直接int a【maxn】,b【maxn】;(改时只改宏定义)
字符串作为函数参数也应该这样写:‘S’……。
有时memset会比循环赋初值为0慢,超时的时候尝试之
strncmp(p1,p2,n);返回判断从两个地址开始,向后n位是否相
同。(包含在cstring中)
strncpy(res,str+c,n);——将从str的第c位开始复制n位给res。后面可以输出res。

cin.getline(str, size_t, ‘,’);  读入字符串到str中,长度不超过size_t和以逗号为结 束符(可以延伸为其它符号未结束符),最先满足原则, 丢掉逗号,加\0。(省略第三个参数时,默认为 \0.。

strstr(str1,str2)
str1: 被查找目标 string expression to search.
str2: 要查找对象 The string expression to find.
返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。

例子:
123 char str[]=“1234xyz”;char *str1=strstr(str,“34”);cout << str1 << endl;
显示的是: 34xyz

有了指针,就可以灵活处理字符串。因地制宜,例如,字符串的反向查找……

几个和内存有关的函数返回是void void * memcpy(void , const void , size_t); size_t 相当于unsigned int
相关语法:内存复制可能是整数,浮点数,和字符串,函数的指 针参数不能确定是哪一种,用void代表无类型,继而转换成其他 类型的指针。
例如:int a【10】:p= (int
) memcpy(b, a, 40);
char s[10]= "
*******"; char d[10]; char * p; p=(char)memcpy(d, s, 10);
字符串按字典序排序,若用指针数组,排之,可以不用一一复制字符,可以直接换指针。
若p, q 是指针变量,n是整数语法不对, ,则n-q+p可以改成:n-(q-p),物以类聚
‘\0’ 就是 0;
字符串换成整数比较大小时,留意一下是否把’\0’也换算比较了!!因显示原因,无法显示。
while (cin.>> ch) 对编程网格有用,本地无用相当于while(1)
俄而此时可以“Ctrl + z”来停止
而网格上的while(1)会零输出 ,不知道为什么
flag改动的时机比较微妙,(不要自己改动,自己判断,多用了)
sqrt头文件是cmath
当数组元素为浮点型时,随便设一个mmax时,也要设成浮点型,要不然冒泡排序会出错——注意变量类型,int不是万能的!
结构体数组,实际为多个相关数组的一套,方便同时置换,心中有序,或者为了下标另有目的,也可以不用。
sort(activity, activityt + n, comp); //排序
bool comp(T t1, T t2)
{
if(t1.end != t2.end)
return t1.end < t2.end;
return t1.start;
}

int dx[] = { -1,-1,-1,0,0,1,1,1 };
int dy[] = { -1,0,1,-1,1,-1,0,1 };八个方向
fin.read ((char*)(&temp), sizeof (course)); // 果然因为eof 的特点,应先读一个
while (!fin.eof())
md5 / sha-1 用来加密,保存码
1.cin >>
遇“空格”、“TAB”、“回车”都结束

char a[20];
cin>>a;
cout<<a<<endl;
1
2
3
输入:jkljkl jkljkl //遇空格结束
输出:jkljkl

2.cin.get()
用法一:从指定的输入流中读取一个字符,返回值就是这个字符。读取到文件结束符就返回EOF,一般以-1代表EOF。

//用于舍弃输入流中的不需要的字符:
cin.get
//读取一个字符:
char ch;
ch=cin.get();
//循环读取:
while((cin.get()!=EOF)){}
//用于判断:
if((cin.get()!=’,’)) break;

用法二:读取一个字符,赋值给ch,读取成功返回非0值,遇到文件结束符就返回0。

//读取一个字符:
char ch;
cin.get(ch);

用法三:cin.get(字符数组/字符指针,接收字符数目) 用来接收一行字符串,可以接收空格 /// getline可用

//字符数组
char c[20];
cin.get(c,10,’\n’);
//字符指针
char* c;
c = new char[20]; //动态指针使用前需要分配内存
cin.get(c,10,’\n’);

3.cin.getline( , , )
和cin.get( , )类似,接受一个字符串,可以接收空格并输出。

char m[20];
cin.getline(m,5);

输入:jkljkljkl
输出:jklj

接受5个字符到m中,其中最后一个为’\0’,所以只看到4个字符输出。

延伸:
cin.getline()实际上有三个参数,cin.getline(字符数组/字符指针,个数,结束字符)
当第三个参数省略时,系统默认为’\0’ 扔掉回车,加\0.,同理,如果是“,”之类的也会被扔掉,所以接下来不用再舍弃之
如果将例子中cin.getline()改为cin.getline(m,5,’a’),当输入jkaljkljkl时,输出jk。

4.getline()
接收一个字符串,可以接收空格并输出,需包含“#include”

string str;
getline(cin,str);

输入:jkl jfksldfj jklsjfl
输出:jkl jfksldfj jklsjfl

和cin.getline()类似,但是cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数。

深度优先:先顺着一条路径递归到头,然后尝试下一个:dfs
其中需要回溯的量(全局的或者对其他的层函数有影响时,需要在
该 层的末尾取消限制或者加减,乘除(取消选择))
广度优先:见后

影子数组:一个遍历,一个记录当下最优
上下左右四个方向,与dx,dy中的i联系起来来判断是否转弯(保留记录下来,与后面的标记可知)
为保证不回去或者浪费,记录是否走过,进行标记
某种情况下,即结果只与数字有关,且算一个数的时候会经过较小数的运算时,可以直接自己构造大数运算记忆,测试输入的小数直接利用遗产

switch 使用格式示例:
switch (level)
{
case (1) : cout << “Not safe” << endl; break;
case (2) : cout << “Medium safe” << endl; break;
case (3) : cout << “Safe” << endl; break;
default : cout << “Error” << endl;
}

时间年月的题目,注意年初,年尾。可以用月日数组来判断几月.例如:m2 = m1 + 28.

由一道照亮所有角落的题所学到的: 首先,凸多边形不一定有工字型,因为凸多边形的定义是,没有优角的多边形,或者是图形分布在任何一条边的一侧的图形。 其次: 没有工字型的图形也不一定能被照亮,例如:阶梯型。 再次: 能被照亮的也不一定是凸多边形,例如:凸字形。 综上: 能被照亮的是:所有分块矩形有公共点的多边形。其实也不对,再次综上: 是在所有边的直线一侧的交集!!(多边形的核)
自学c语言算法(不知长久)
最后是“Area = %.3f\n”,该语句的用法很容易被猜到:只有以“%”开头的部分才会被后 面的值替换掉,其他部分原样输出。
提示1-9:printf的格式字符串中可以包含其他可打印符号,打印时原样输出。
上面的程序输出025,但要改成输出25似乎会比较麻烦——必须判断n%10是不是0,但 目前还没有学到“根据不同情况执行不同指令”(分支结构程序设计是1.4节的主题)。 一个解决方法是在输出前把结果存储在变量m中。这样,直接用%d格式输出m,将输出 25。要输出025也很容易,把输出格式变为%03d即可。
a = a + b;
b = a - b;
a = a - b; 啊,好厉害
C语言中的逻辑运算符都是短路运算符。一旦能够确定整个表达式的值,就 不再继续计算。所以,可以把必要的(比如控范围)或者难以满足的,或者较简单判明的放在前面
int a;
scanf ("%d", &a);
printf (“a = % .1f \nb = %.3f”, sqrt(10), a);
输出 a = 3.2 b = 0.00 (与输入无关)
NaN(Not a Number,非数)是计算机科学中数值数据类型的一类值,表示未定义或不可表示的值。常在浮点数运算中使用。(计算0.0 / 0.0 或者负数开方时输出这个)
浮点数范围比整型数大得多,少越界
INF / inf:这个值表示“无穷大(infinity 的缩写)”,即超出了计算机可以表示的浮点数的最大范围(或者说超过了double 类型的最大值)。
:如果 真的要输出斜线“\”和字符n,怎么办?方法是“printf("\n");”,编译器会把双斜线“\”理解 成单个字符“\”,不止是c,c++亦然,可能所有都如此?不知道,,
如何在printf的格式串中输出一个’%'字符?我试过%,但是不行。
答:只需要重复百分号:%%。
用printf输出%之所以困难是因为%正是printf的转义字符。任何时候printf遇到%,它都会等待下一个字符,然后决定如何处理。而双字符序列%%就被定义成了单独的%字符。
并由此可知,输出%d为: printf (“%%d”);一个d就行,也理应如此
假设在经过大量计算后,由于误差的影响,整数1变成了0.9999999999,floor的结果会 是0而不是1。为了减小误差的影响,一般改成四舍五入,即floor(x+0.5)(2)。如果难以理 解,可以想象成在数轴上把一个单位区间往左移动0.5个单位的距离。floor(x)等于1的区间 为[1,2),而floor(x+0.5)等于1的区间为[0.5,1.5)。 提示2-7:浮点运算可能存在误差。在进行浮点数比较时,应考虑到浮点误差。
回忆一下,记得以前记过,输入数据没有溢出时,中间过程例如乘法运算也可能溢出!!
用下面来计算程序花费的时间
#include <time.h>
printf(“Time used = %.2f\n”, (double)clock() / CLOCKS_PER_SEC);

:可以使用time.h和clock()函数获得程序运行时间。常数 CLOCKS_PER_SEC和操作系统相关,请不要直接使用clock()的返回值,而应总是除以 CLOCKS_PER_SEC。

输出的Time used居然不是 0!其原因在于,键盘输入的时间也被计算在内——这的确是程序启动之后才进行的。为了 避免输入数据的时间影响测试结果,可使用一种称为“管道”的小技巧:在Windows命令行下 执行echo 20|abc,操作系统会自动把20输入,其中abc是程序名(8)。如果不知道如何操作命令 行,请参考附录A。笔者建议每个读者都熟悉命令行操作,包括Windows和Linux。

while (cin》》n)的情况下:
能告诉程序输入结束了呢? 提示2-19:在Windows下,输入完毕后先按Enter键,再按Ctrl+Z键,最后再按Enter 键,即可结束输入。在Linux下,输入完毕后按Ctrl+D键即可结束输入。

在算法竞赛中,有经验的选手往往会使用条件编译指令并且将重要的测试 语句注释掉而非删除。
:在算法竞赛中,偶尔会出现输入输出错误的情况。如果程序鲁棒性强,有 时能在数据有瑕疵的情况下仍然给出正确的结果。程序的鲁棒性在工程中也非常重要。
:在多数据的题目中,一个常见的错误是:在计算完一组数据后某些变量没 有重置,影响到下组数据的求解。
当嵌套的两个代码块中有同名变量时,内层的变量会屏蔽外层变量,有时 会引起十分隐蔽的错误。
第2章的程序很实用,也发挥出了计算机的计算优势,但没有发挥出计算机的存储优势
//2019/01/11 21:38
在上述程序中,数组a被声明在main函数的外面。请试着把maxn定义中的100改成 1000000,比较一下把数组a放在main函数内外的运行结果是否相同。如果相同,试着把 1000000改得再大一些。当实验完成之后,读者应该就能明白为什么要把a的定义放在main函 数的外面了。简单地说,只有在放外面时,数组a才可以开得很大;放在main函数内时,数 组稍大就会异常退出。!!!!
如果要从数组a复 制k个元素到数组b,可以这样做:memcpy(b,a,sizeof(int)*k)。当然,如果数组a和b 都是浮点型的,复制时要写成“memcpy(b,a,sizeof(double)*k)”。另外需要注意的是, 使用memcpy函数要包含头文件string.h。如果需要把数组a全部复制到数组b中,可以写得简单 一些:memcpy(b,a,sizeof(a))。
函数原型
编辑
void *memcpy(void *dest, const void *src, size_t n);
功能
编辑
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中

strcpy 和 memcpy都是标准C库函数,它们有下面的特点。
strcpy提供了字符串的复制。即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符。
已知strcpy函数的原型是:char* strcpy(char* dest, const char* src);
memcpy提供了一般内存的复制。即memcpy对于需要复制的内容没有限制,因此用途更广。
void *memcpy( void *dest, const void *src, size_t count );

strcpy和memcpy主要有以下3方面的区别。
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
2018/12/28 21:50
:在很多情况下,最好是在做一件事之前检查是不是可以做,而不要做完再后 悔。因为“悔棋”往往比较麻烦。
如果越界,x+1会等于n,a[x+1][y]将访问 非法内存!幸运的是,这样的担心是不必要的。“&&”是短路运算符(还记得我们在哪里提 到过吗?)。如果x+1<n为假,将不会计算“!a[x+1][y]”,也就不会越界了。
tot = a[x=0][y=n-1] = 1; 表达式也有值
蛇形填充数组,
while(tot < n*n) {
while(x+1<n && !a[x+1][y]) a[++x][y] = ++tot;
while(y-1>=0 && !a[x][y-1]) a[x][–y] = ++tot;
while(x-1>=0 && !a[x-1][y]) a[–x][y] = ++tot;
while(y+1<n && !a[x][y+1]) a[x][++y] = ++tot;
}

简洁!
注意这里的%5d,它表示按照5位数打印,不足5位在前面补空格(还记得%03d 吗?)。
提示3-8:C语言中的字符型用关键字char表示,它实际存储的是字符的ASCII码。字符
常量可以用单引号法表示。在语法上可以把字符当作int型使用。
另一个新内容是“scanf("%s", s)”。和“scanf("%d", &n)”类似,它会读入一个不含空格、 TAB和回车符的字符串,存入字符数组s。注意,不是“scanf("%s", &s)”,s前面没有“&”符 号。
提示3-9:在“scanf("%s", s)”中,不要在s前面加上“ & ”符号。如果是字符串数组char s[maxn] [maxl],可以用“scanf("%s", s[i])”读取第i个字符串。注意,“scanf("%s", s)”遇到 空白字符会停下来。
。strchr的作用是在一个字符串中查找单 个字符,而这个sprintf似曾相识:之前用过printf和fprintf。没错!这3个函数是“亲兄 弟”,printf输出到屏幕,fprintf输出到文件,而sprintf输出到字符串。
提示3-19:善用常量数组往往能简化代码。定义常量数组时无须指明大小,编译器会 计算。
-n的内部表示是 232-n。这就是著名的“补码表示法”(Complement Representation)。,只需要直接相加,并丢掉最高位的进位即可。“
:建议把谓词(用来判断某事物是否具有某种特性的函数)命名成“is_xxx”的 形式,返回int值,非0表示真,0表示假。
以数组为参数调用函数时,实际上只有数组首地址传递给了函数,需要另 加一个参数表示元素个数。除了把数组首地址本身作为实参外,还可以利用指针加减法把其 他元素的首地址传递给函数。
//j[1]–;j[2]–;j[0]–; changdu!!!buyongjian!!lingkaishi!!!
Sort函数有三个参数:
(1)第一个是要排序的数组的起始地址。
(2)第二个是结束的地址(最后一位要排序的地址的下一地址)
cin.getline (s, 100, ‘,’); 会让,变成\0,赋值下一个字符串的时候,不必再欲吃掉这个逗号。见前
队列下标开的大一点,因为不知道要走多少步
队列关注头尾的相对距离,头:用来标记谁当下在扩展,尾标记当下最新扩展
#pragma GCC optimize(2)可置于首,手动开 o2 优化(较严格,但快)
广度优先:定义一个数组,下标是(队列)位置,值是层数,标记第一个与最后一个,不断延展,依次放入队列,依次延展,类似水漫金山 此外,勿忘标记已经走过的点
在函数中不要开太大的数组,如需,全局之
八个方向走,也可以只开两个数组,dx,dy
每时每刻判断是否越界,或者出迷宫范围
皇后走法时,欲标记可至范围可用两个循环,一个八个方向,另一个不断乘上一个数,判断是否可至,用一个数组分别记录就行了
由此可知:多个数组下标,不同变化,可灵活应用,不必与循环变量同步
队列初始元素可有多个,同时扩展
比较谁离得近,不能到达的地方应该设的距离最大,要不然可以到达的一方无缘无故受屈
考虑每一步的先后顺序,有可能会有相互影响。例如:取消,与放子。清零与赋值
注意++ 与 ++ 的区别,例如或者尤其在两个成对的矩阵同时赋值时:要么x【++t】,y【t】 要么,x【t】,y【t++】。而在队列中一般前者,因为若t++,则t不再保持数量,所以应该++t,即需要的时候加,或者 直接在前面解决入队问题
注意取消效果,与设置效果的时机,例如与循环的相对位置
临时更改或者添加的变量名,统一!!!!全改!!
随时更新最大值!!勿忘!!
cmath 中 的 fabs函数
表示一个较小数 1e-6
if (x) 之后加除法操作
赋值字符的时候,在定义时用双引号赋值整串,在函数中用单引号赋值单个字符,其中\要多加一个,用来做转义字符。
什么时候用DFS,什么时候用BFS?

二维数组的题目,N小于20的,适用DFS。而一般 N<= 200,N<=1000这种,一定不可能用DFS去做。而且并不只是整个题目不能用DFS,其中的每一步也不能使用DFS。 (此外,全部解deep比较好,最近解brand比较好)

BFS的基本步骤

1.将初始点(一个或多个)加入一个集合尾

2.从集合头取出点,判断初始点的周边点,将符合条件的点加入队列

3.重复2操作,直至集合为空。(一般每个点只加入队列一次)

一般来说用DFS解决的问题都可以用BFS来解决。
DFS(深搜的同时考虑回溯)
bfs=队列,入队列,出队列;dfs=栈,压栈,出栈
bfs是按一层一层来访问的,所以适合有目标求最短路的步数,你想想层层搜索每次层就代表了一步。bfs优先访问的是兄弟节点,只有这一层全部访问完才能访问下一层,也就是说bfs第几层就代表当前可以走到的位置(结点).而dfs是按递归来实现的,它优先搜索深度,再回溯,优先访问的是没有访问过的子节点
DFS多用于连通性问题因为其运行思想与人脑的思维很相似,故解决连通性问题更自然。BFS多用于解决最短路问题,其运行过程中需要储存每一层的信息,所以其运行时需要储存的信息量较大,如果人脑也可储存大量信息的话,理论上人脑也可运行BFS。
总的来说多数情况下运行BFS所需的内存会大于DFS需要的内存(DFS一次访问一条路,BFS一次访问多条路),DFS容易爆栈(栈不易"控制"),BFS通过控制队列可以很好解决"爆队列"风险。
它们两者间各自的优势需要通过实际的问题来具体分析,根据它们各自的特点来应用于不同的问题中才能获得最优的性能。

猜你喜欢

转载自blog.csdn.net/weixin_44489823/article/details/87938239