《算法竞赛入门经典》第四章总结

例题
4-1

两串字符串都只要,统计不同字符的出现次数,
然后排个序,如果从小到大都相等则输出YES,否则输出NO

4-2

好坑= =如果单词已经全部猜完直接跳出,
我还以为如果此时如果猜的还有= =任要继续呢

4-3

这题很妙的是用-1,1两种步长来表示两种方向,
刚开始我还再想如果到了负数%怎么用,白书更妙的是每次从n-1开始这样增张减少都可以都可以

4-4

这题最终要的就是练习了多行输入= =
以后这种多行输入就用他这个函数了,
int readchar()
{
for(;;)
{
int ch=getchar();
if(ch!='\n'&&ch!='\r')
return ch;
}
}
while(readcodes())
{
}
和再readcodes()中通过来
if(ch==EOF)return 0;
if(ch=='\n'||ch=='\r')return 1;

4-5

两个方法,感觉都挺妙的,第一种是就是整体模拟这个过程。好方法
1.通过一个type把操作统一
2.删除中 用if(!cols[i])copy(type,++cnt2,i);
插入用if(cols[i])copy(type,++cnt2,0);
copy(type,++cnt2,i);
3.通过BIG来记录自生原来的位置,(刚开始我还再想要不要开个结构体来存储行和列)
第二种是记录操作直接输出所求单元在这一系列变化后的位置。

4-6

这题本身不是很难就是比较烦,注意删除和查找可以统一,以及,对求平均数之类要价格EPS来减小误差。

课后练习题
4-1

刚开是直接判断将是否符合题目的要求,但是发现非常难写,
因为还要考虑红方子被吃掉的情况,后来改成,
将将朝四个方向都移动一下,然后在新的棋盘上再次判断,
这样比较好些 = =因为不知道如果上来将和帅就是相对的这种情况该怎么判= =
两个ac的程序给的答案不一样,最后花了快30个小时这题也没有ac掉。
处理技巧用数组存放位移量,如将的```
dx[]={-1,-1,0,0},dy[]={0,0,-1,-1}
for(int i=0;i<4;i++)
{
cnt+check{r+dx[i],c+dy[i]);
}
模拟出位移四个方向后的情况,这种模拟题最好不要用if else这样比较乱。
我刚开始的思路是,每个棋子超它可能的位置,前进如果能碰到将就算将军,
这样很麻烦,每个旗子都要检查一遍,如果我们反过来想
,检查将周围的情况,看看他是否处于被攻击的状态,这样就比较简单了,注意缩写可以统一的情况比如帅和车的列方向,检查时要注意不要超过棋盘,
马的情况也可以用数组来```
int hx[] = { -2, -1, -2, -1, 1, 2, 1, 2};  //马将军
int hy[] = { -1, -2, 1, 2, -2, -1, 2, 1};
int tx[] = { -1, -1, -1, -1, 1, 1, 1, 1};  //马蹩脚
int ty[] = { -1, -1, 1, 1, -1, -1, 1, 1};
for(int k = 0; k < 8; ++k)   //被马将军
    {
        tr = r + hx[k], tc = c + hy[k];
        if(tr < 1 || tr > 10 || tc < 1 || tc > 9) continue;
        if(brd[tr][tc] == 'H' && (!brd[r + tx[k]][c + ty[k]]))
为复杂的用一个空间未2的cr,和cc分别储存行和列,
如果与将在同一行且前面有个棋子则判成功。注意本身位置可不判,因为将必移动。

4-2

= =
我感觉我写的比网上的简洁,思路就是用一个无向图存储两个点之间是否有通路
然后从左到友从上到下,正方形周长不断扩大,看看走一圈的周长是否等于该边长应有的周长。
网上的思路是最外层是长方形的长度,然后分别从每个点出发寻找

4-3

这题我没有写,感觉思路不太好,自己写会很烦,
看的大佬的程序
思路就是用一个变量currplay来记录是黑白双方谁动,然后根据三个操作,分别对应模拟,主要是list和Move这两个操作,他们都需要用到一个find函数来判断一个位置放上棋子后是否会有其他棋子变化。
move函数首相通过if (!find(r, c, false))来判断是否切下棋者,然后题目告诉了不会出现双方操作都不合法的情况因此,之后紧跟着一个 find(r, c, true);对于list则是一样,对每个位置开始判断是否,可以吃到别的子
重点就是find函数,对于他也是用两个数组来存放,周围的位置
int dx[8] = { -1, -1, 0, 1, 1, 1, 0, -1 };
int dy[8] = { 0, 1, 1, 1, 0, -1, -1, -1 };

4-4

对每个方向都通过一个队列去模拟,如果与本位置,的棋子不一样则继续朝那个方向移动
,如果一样则该方向停止,把吃掉的棋子变色其他情况直接跳出。
路是一个正方形不动,另一个正方形,分别以6个点环绕一圈,这24种状态只要有一种满足即可,
刚开始我以为侧面只要各种颜色,顺序一样即可
,后来发现上下面也需要一一对应,不然翻转后,侧面位置不对应

4-5

我的方法比较麻烦完全用字符串来处理的,不太好,
网上有个大神直接利用整数做的,而且我刚开始对于怎么排除数字之间的点很是头疼,
太蠢了没有想到这样就可以了
scanf("%d.%d.%d.%d",&ip[0][i], &ip[1][i], &ip[2][i], &ip[3][i]);
 然后将每一块的IP地址排序
由于子网掩码只有那九种情况可以用一个数组直接预存下。真是妙啊,主要还是我太蠢。

4-6

刚开始我以为是动态规划 ,直接就没做了
先用个数组把莫尔斯密码存起来,然后根据每个字母或者数字的表示,
把那些单词组合起来,原来是在尾部,那样的话,每次如果公共前缀相同,
距离就是他们的距离差。

4-7

看了代码才把程序看懂我了个去,我想复杂了,就是记录每一行对应的
10,x,的位置,如果,x大于等于2这时就没办法知道他们具体是1还是0了,
其他通过奇偶性,来确定x的值,和判断该列数据是否合法,
根据自顶而下的设计方式,这个程序应该有三个函数main,judge,和print。
教训:
1.认真观察样例:样例给的原始数据为自上而下,而不是自左向右!
2.注意好细节:原文最后讲到:Ifnecessary,addextra‘0’bitsattheend of 
the recovered data so the number of bits is always a multiple of 4.
如果整个数据长度不是四的倍数,则需要补额外的0来达到4的倍数!

4-8

这道题我看了很久,实在想不到如何表示,后来发现题目的(A,B,C)
就是一个很好的表示方法,时间用一个for循环表示,
定的大一点,如果在这个范围内都没有出现那就输出-1了,
没个循环怎家c如果到了睡觉的时候判断能不能不能重新从1开始。

4-9

这题我没看懂题意,看解析的这么简单,
注意因为可能会爆int所以用long long.直接暴力搜索A,B,居然都不给A,B范围。

4-10

这题真的很好,重点就是如何找到,水的最终位置是在哪个海拔区间之内,
思路1,是每次上升一个海拔,然后用已经加进去的总体积,减去该加的V如果小于零则找到,
思路2 把所有格子按海拔顺序排序,逐个计算含水海拔,
第n个格子的含水海拔等于(总水量+n个格子相对于0海拔的体积)/n个格子的面积和,
顺序读入后面格子海拔,如果此格高于已算出的含水海拔则终止。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值