呜呜呜呜呜,被虐爆了……
第一题就不知道怎么做,后来自己归纳了一下才发现象棋的规律,还因为写错了一个地方被challenge了,呜呜呜呜,我简直弱爆了。
第二题组合数学加动态规划,第三题估计也是动态规划,完全没有思路。。。。
我还是滚去好好学我的离散数学吧。。。。
division2的第三题真是好题,让我下午做了整整3个小时,最后卡时过了(标程应该也超时吧……)
分析可见http://apps.topcoder.com/wiki/display/tc/SRM+564,非常非常精彩,强烈推荐。
我的代码:
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <queue> #include <string.h> #include <ctime> using namespace std; class KnightCircuit { public: long long maxSize(int, int, int, int); int gcd(int a, int b); long long bfs(int w, int h, int a, int b); }; //when the scale is very small, just use breath first search long long KnightCircuit::bfs(int w, int h, int a, int b){ bool** check = new bool*[h+1]; for(int i=0; i <= h; i++) check[i] = new bool[w+1]; //mark the corresponding directions int dir_x[]={a, a, -a, -a, b, b, -b, -b}; int dir_y[]={b, -b, b, -b, a, -a, a, -a}; long long goal=0; clock_t start=clock(); for(int m=0; m<h; m++) for(int n=0; n<w; n++){ clock_t end=clock(); if((double)(end-start)/CLOCKS_PER_SEC > 1.0) return goal; for(int i=0; i<=h; i++) for(int j=0; j<=w; j++) check[i][j] = false; check[m][n] = true; queue<int> q; while(q.empty() == false) q.pop(); q.push(m); q.push(n); long long res=1; while(q.empty() == false){ int x = q.front(); q.pop(); int y = q.front(); q.pop(); //search for the next step for(int i=0; i<8; i++){ int tmp_x = x + dir_x[i]; int tmp_y = y + dir_y[i]; if(tmp_x < 0 || tmp_y < 0 || tmp_x >= h || tmp_y >= w) continue; if(check[tmp_x][tmp_y] == false){ check[tmp_x][tmp_y] = true; q.push(tmp_x); q.push(tmp_y); res++; }//end if }//end for loop }//end while loop goal=max(goal, res); } return goal; }//end method bfs //hunt for the greatest common divisor using Euclid method int KnightCircuit::gcd(int a, int b){ while(a > 0){ int c = a; a = b % a; b = c; } return b; } long long KnightCircuit::maxSize(int w, int h, int a, int b) { int g = gcd(a, b); //minimize the scale of problem if( g != 1) return maxSize((1 + (w - 1)/g), (1 + (h - 1)/g), a/g, b/g); //just use breath first search if((w <= 20) || (h <= 20)) return bfs(w, h, a, b); //all positions are reachable if((a + b) % 2 == 1) return w * (long long)h; //only half positions are reachable else return (1 + (long long)w * h)/2; } // //Powered by [KawigiEdit] 2.0!