date: 2019-03-09 20:08:00
第一次软构实验
第一次的软构实验本来以为会非常简单,但是没想到坑点那么多。从需要的算法层面来说确实不难,但是细节的处理还是挺麻烦的,感觉和传统的ACM竞赛题有比较大的区别。
接下来就对整个实验过程做一个描述吧。
P1
最让人没想到的是第一个实验竟然在验收的时候出问题了。
嘛,虽然学长是用非法数据卡掉了我的代码,但是别人的都没啥错误emmm貌似只有我的被卡掉了。
所以一定要记住PDF中的只是部分的要求!(指合法数据方面)
P1应该来说是真的是最简单的一个了,但是就算是P1都被我搞成这个鬼样子。
这里显然,应该使用这个方法:
Integer.valueOf(String s)
并且比较容易发现的是,这个方法可能会抛出异常,当且仅当这个字符串里面包含非法字符。
所以除了所谓的-.之外,对这个方法调用可能产生的异常我们就认为是包含了非法字符。
所以大家应该也都发现了……
ACM竞赛和软构的区别就是
ACM竞赛保证输入是合法的,软构还应该对可能出现的异常进行处理。
这个……行吧。(这仇我记下了)
P2
P2如果不看文档感觉很难理解turtle是个啥玩应。
看完之后才知道,turtle是一个用矢量画图的工具。(别较真,我知道矢量没有粗细)
那么海龟汤,咳,TurtleSoup里面需要实现什么呢?
前面的几个感觉很简单嘛,就是数学题。
唔,真要说比较难的话,计算转角的那个稍微有点困难。
但是很容易想到,这是一个类似钟表盘的转法,所以我们只要当成钟表盘就好啦!
数学中是逆时针的,钟表是顺时针的,所以乘-1再加上一周就可以转换啦!
重点介绍一下……凸包(Convex Hull)
庆幸没出三维凸包
常用的算法就是两个,卷包裹法和Graham算法,都是计算几何系列中比较常见的算法。
很容易想到,从一个凸包上的点A到凸包上与A相邻的点B连线,所有的点必然都在同一侧。
而这就涉及一个方向和构造方法的问题了,这里我们假定是顺时针构造,A的下一个点就是B,那么对于之前提到的AB两点,不可能存在C点,使得AB叉乘AC大于0。(根据右手定则,如果上式成立,说明AB向量逆时针旋转一点就能到AC,那就是说C不在凸包内,推出矛盾)
共线的判定很简单,只需要在等于0的时候选择离得最远的就行了。
下图是Wikipedia上演示的卷包裹法的构造方法,看上去非常直观容易理解。
剩的感觉没啥难点了
除了那个Personal Art
分享一组自己乱调搞出来的?
8说了,开冲!
P3
P3是那个社交网络,简单的BFS,但是感觉写麻烦了……我用了map存了一组关系,似乎……没太有必要?
BFS模板如下:(伪代码)
queue <Node> q;
int bfs(Node beg,Node ed) {
while (!q.empty()) q.pop();
if (beg == ed) return 0;
vis[beg] = true;
q.push(beg);
while (!q.empty()) {
Node i = q.front(); q.pop();
for (Node j : Edge_from_i) {
if (!vis[j]) {
vis[j] = false;
j.step = i.step + 1;
if (j == ed) return j.step;
q.push(j);
}
}
}
return -1;
}
大概就是这么回事。
队列的作用就是保证得到的结果是最小的,因为当队首元素是第i步时,后面不可能存在i-1步的元素。
根据上面的模板,person类的设计就变得显然了。
P4
最复杂的一个部分,实在写不动了就偷了个懒。
大佬们都在用正则,只有我在滚键盘用split23333333
这个就是……只要思路正确就不会有问题。
不太熟悉的操作就是比较类的声明方法罢,总忘了加Type,没有IDE写不了代码系列。
例子:(说实话我从来都不记得compare里面1是什么-1是什么,所以每次都是写完之后测一测防止出错)
class MyComparator implements Comparator<Type> {
MyComparator() {
}
public int compare(Type t1,Type t2) {
return t1.compareTo(t2);
}
}
然后……介绍一个奇技淫巧
就算写错了也不打紧!
可以这么写!
class MyComparator implements Comparator<Type> {
boolean order;
MyComparator() {
order = true;
}
MyComparator(boolean t) {
order = t;
}
public int compare(Type t1,Type t2) {
return t1.compareTo(t2) * (order ? 1 : -1);
}
}
实例化的时候随便用一个,测一测,如果对了就对了。
如果错了就把原来声明的真值翻转一下(笑)
不过话说回来又用了一次map……总感觉自己写的是不是过于麻烦了……
就这么多吧,稍微有点懒得写了……
小结
Java还是写的太少了,不太习惯那些常用的写法,希望多写会好一点罢。
然后我想说句题外话:
我即使是几乎去世,瘫倒在Java的面前了,也要在电脑面前,用这腐朽的声带喊出:
哟咦哟咦咚哒哟!