《算法竞赛入门经典训练指南》第一章1.1,1.2

来源:互联网 发布:linux 强行退出vim 编辑:程序博客网 时间:2024/05/22 05:27

例题1:水题

例题2:水题,但是证明还是比较麻烦的,书上给的证明感觉不好理解,我们可以给证明中各项任务的执行时间和吩咐时间赋上具体的值。有个技巧是求总时间时
s+v[i].b;
ans=max(ans,s+v[i].j),因为吩咐时间都是要加上的,执行时间只要留下那个向后延时最远的那段的末端位置就行了。

例题3:这题,没做过,鬼知道,但是做过了一定要弄清楚。
-x1,x2加的原因是因为这样每个数处理方式都是相同的左边减右边加,不然有的数需要两个+,有的是两个减没法处理、
因为每个人最后手中的球数是固定的假设为M
A1-x1+x2=M;
A2-x2+x3=M;
;
;
;
An-xn+x1=M;这个式子多余的原因是将上面的式子相加,得A1+。。+A(n-1)-x1+xn=(n-1)M;对这个式子移项x1-xn=-(n-1)M+A1+。。+A(n-1)两边同时加An得
An-xn+x1=A1…A(n-1)-(n-1)M右边的就是等于M
这个式子换个方法理解就是你总数知道,其它人也知道,自然An也就知道了所以这个式子是无效的
这样n-1个式子有n个变量不能直接求解
那个绝对值之和中|x1|是因为最后一个式子An-xn+x1=M将上面求出的xn表达式带入,因为An+,,A1和nM相等所以就等于0;
这个定理一定要记住
最后那个白书上面的小知识点也要掌握如%lld占位符不是跨平台的,解决cin/cout慢的方法如下:
cin慢是有原因的,其实默认的时候,cin与stdin总是保持同步的,也就是说这两种方法可以混用,而不必担心文件指针混乱,同时cout和stdout也一样,两者混用不会输出顺序错乱。正因为这个兼容性的特性,导致cin有许多额外的开销,std::ios::sync_with_stdio(false);这个语句可以禁用这个特性,这样就可以取消cin于stdin的同步了

例题4
这题也算是个技巧题如何求,最短移动距离,先把10000的环缩小成n+m这样每个整数点都是新的位置,然后巧妙的利用floor(x+0.5)这个式子来求距离一个点最接近的整数,也就是最接近的分配点
后面那个证明一个点没动,想不懂,以后在说把。
第二个证明意思是如果你两个雕塑最后移动到同一个点那他们的距离也是1的差距如1.49999和2.49999的差距,但是现在n+m个的差距就是1,原来的只能比它大不能比他小,所以不会出现两个雕塑移动到同一个地方的情况发生。

例题5
这题思路==还是记住吧,我是看题解的,就是想要几次排序比较难想,首相因为蚂蚁的移动速度和大小都是相等的,当考虑整体时,及时两者相撞,最后整个木棍上蚂蚁出现的地方也是固定的,只是对于个体而言是有区别的,另外记住蚂蚁的相对位置是永远不会改变的,比如刚开始是a,b,c不管如何相撞都是a,b,c因为它们无法穿过,此题输入时就不是按照顺序位置顺序排序的,所有刚开始先给每个蚂蚁一个id然后最后输入的时候按1-》n的id输出,接下来按位置排序,在根据每只蚂蚁的移动方向和位置,不考虑相撞情况,直接求出下一秒所有蚂蚁的位置,再按照上面那个那位值排序的顺序一一赋值,最后按id1-》n输出。

例题6:
首先先建立一个空间坐标系,白书是以正面左上角为坐标原点的因为第一个方格位置是(0,0,0),所以在设置坐标与方格对应关系时要注意,所有面建立平面坐标系时要选用相同的坐标原点,一般选左上角为平面原点,然后设置一个pos来存储方格的状况,注意处理’.’时没有break是因为,如果改为空,可以继续往下删除,而如果是有颜色就要及时用break退出REP(p,n)这个循环不能在往下,因为透视图只是反映了表面的情况。
技巧有两个
int x,y,z;
get(k,i,j,p,x,y,z)因为x,y,z的位置的是引用参数,直接就能操作x,y,z这样就能把删除循环留在主函数中,不易出错,
//# define REP(i,n)for(int i=0;i<(n);i++)精简代码

例题7:
这题给我影响最大的是二进制表示的是换与不换而不是该位置是0还是1,记住几个大概的数据,2^15约等于32768,每次当我们面对一个棋盘的时候一般是无法枚举整个棋盘的装态的,但是如果后面的可以根据前面的退出,那我门可以通过枚举一行推出所有的情况。
我们也可以枚举第一行1和0的排列情况来做只需要将第一行的的枚举语句换成下面这个就行了

    for (int i = 1; i <= n; i++)    {        if (s & 1 << i - 1)//出现11        {            temp[1][i] = 1;        }    }    for (int i = 1; i <=n; i++)    {        if (temp[1][i] == 0 && board[1][i] == 1)//该情况是该位是0但是原来位是1错误,1不能变成0        {            return INF;        }    }

例题8:

例题9:因为每次返回时有部分c[i]没有复原,因此从新判断一张来的牌是我要for(j=0;j<13;j++)c[mj[j]]++,恢复手中的牌,麻将对应的符号用以数组中的对应下表来存储。
深搜那部分是重点,dep的判断在if(c[i]>=3)里面就是if(dep==3)return true;在深搜的开始位置怎为if(dep==4),因为总共需要一个对子,4个(顺子+或者三个相同的)

例题10:
这道题做过以后就不会错了,将一片单调数列折半求解,减去下一段第一个高度而不是前一段最后一个高度是因为这样单双数都满足如1 2 3 4 5 6–》1 2 3 0 1 2
1 2 3 4 5 6 7–》1 2 3 0 1 2 3

0 0
原创粉丝点击