绝对是大神级别的题目,第一次做感觉完全没有思路,看解答之后感觉:其实也挺简单的。。。
这题主要是涉及概率论中的期望计算,以及期望的线性性质。
数据类型的转换非常重要,否则有可能会造成溢出。
题目分析在这,非常非常好:http://apps.topcoder.com/wiki/display/tc/TCO+2013+Round+1C
#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 <ctime> using namespace std; // About probability and expected values // Take advantage of the linearity of expected values // and divide the original problems // Transformation of data type is very important in solving this problem class TheKnights { public: double find(int, int, int); double single(int n, int a, int b); double inter(int n, int a, int b); }; // Only can be attacked by one knight double TheKnights::single(int n, int a, int b) { //define directions const double dx[] = {a, b, -a, -b, 0, a, b, -a, -b}; const double dy[] = {b, -a, b, -a, 0, -b, a, -b, a}; double res = 0; double p = 1.0/((double)n*n); int i = 9; if(a == b) i = 5; for(int j=0; j<i; j++){ double minx = max(0.0, dx[j]); double maxx = min(n-1+dx[j], (double)n-1); double miny = max(0.0, dy[j]); double maxy = min(n-1+dy[j], (double)n-1); double x = max(0.0, maxx-minx+1); double y = max(0.0, maxy-miny+1); //cout<<"x: "<<x<<endl; //cout<<"y: "<<y<<endl; res += (x*y); } // cout<<"single: "<<res<<endl; return res*p; } // Can be attacked by two knights double TheKnights::inter(int n, int a, int b) { //define directions const double dx[] = {a, b, -a, -b, 0, a, b, -a, -b}; const double dy[] = {b, -a, b, -a, 0, -b, a, -b, a}; double res = 0; double p = 2.0/(((double)n*n)*(((double)n*n)-1)); int i = 9; if(a == b) i = 5; for(int j=0; j<i; j++) for(int k=(j+1); k<i; k++){ double minx = max(0.0, max(dx[j], dx[k])); double maxx = min((double)n-1, min(n-1+dx[j], n-1+dx[k])); double miny = max(0.0, max(dy[j], dy[k])); double maxy = min((double)n-1, min(n-1+dy[j], n-1+dy[k])); double x = max(0.0, maxx-minx+1); double y = max(0.0, maxy-miny+1); res += (x*y); } //cout<<"inter: "<<res<<endl; return res*p; } double TheKnights::find(int n, int a, int b) { return 2*single(n,a,b)-inter(n,a,b); } //<%:testing-code%> //Powered by [KawigiEdit] 2.0!