USACO 3.4.2 heritage & 3.4.3 fence9 解题报告
heritage 这个题本质上是个水到不能再水的题目了。拆解一下就是字符串操作,外带递归就好了。原来在pascal写的时候也很简单,没想到在C++就遇到了意想不到的麻烦。首先C风格的字符串也就是那个脑残的char [],介个东西的各种函数返回值都各种诡异,都是指针神马的。所以最后还是决定用string类,这个东西最大的好处就是方便,缺点就是要慢一些……然后就遇到了个狗血的事情……大家都知道C++中所有的数组,包括什么vector啊string啊神马的都是从0开始标号的(准确的说这货叫偏移量)。而这个等同于pascal中pos的函数find的返回值在没有知道到字串的时候是什么呢……显然不能像pos一样是0,因为这里0是有意义的。后来查了一下,发现了它返回这个悲剧的东西:
string::npos
最脑残的是这个数吧,根本不是什么特殊的数,而是一个乱七八糟的东西。可能还会因机器的不同而不同……总之长了见识了……其他的用到的还有substr,当然其他很好用的还有erase,insert神马的……至今不知道pascal里面的val和str这两个函数怎么在C++里面实现,求大神提供下实现方法(别说手打一个……)。
fence9是个纯数学题,小学教科书上我记得是,写过一个叫做皮克定理的东西……就是在格点中,封闭图形的面积和边界上格点个数以及图形内格点个数的关系。
S = a + b / 2 – 1
其中S是面积,a是图形内格点个数,b是图形边界上格点个数。有了这个这题无限水了吧……
代码:
heritage
/* TASK:heritage LANG:C++ */ #include <iostream> #include <fstream> #include <string> using namespace std; string s1, s2; void init() { cin >>s1; cin >>s2; } void solve(string s1, string s2) { if (s2.length() == 0) return; if (s2.length() != 1) { unsigned int k = s1.find(s2[0]); if (k != string::npos) solve(s1.substr(0, k), s2.substr(1, k)); if (k < s1.length()) solve(s1.substr(k + 1, s1.length() - k - 1), s2.substr(k + 1, s2.length() - k - 1)); } printf("%c", s2[0]); } int main() { freopen("heritage.in", "r", stdin); freopen("heritage.out", "w", stdout); init(); solve(s1, s2); printf("\n"); return 0; }
fence9
/* TASK:fence9 LANG:C++ */ #include <iostream> #include <fstream> #include <cstdlib> using namespace std; int n, m, p, res; int gcd(int x, int y) { if (0 == y) return x; return gcd(y, x % y); } void init() { scanf("%d%d%d", &n, &m, &p); } void solve() { int tmp = gcd(n, m) + p + gcd(abs(n - p), m); res = (p * m / 2) - (tmp / 2) + 1; } void print() { printf("%d\n", res); } int main() { freopen("fence9.in", "r", stdin); freopen("fence9.out", "w", stdout); init(); solve(); print(); return 0; }