呜呜呜呜呜,被虐爆了……
第一题就不知道怎么做,后来自己归纳了一下才发现象棋的规律,还因为写错了一个地方被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!