TCO 2013 round 1C TheKnights

来源:互联网 发布:linux 修改帐号密码 编辑:程序博客网 时间:2024/05/22 00:11

绝对是大神级别的题目,第一次做感觉完全没有思路,看解答之后感觉:其实也挺简单的。。。

这题主要是涉及概率论中的期望计算,以及期望的线性性质。

数据类型的转换非常重要,否则有可能会造成溢出。

题目分析在这,非常非常好: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 problemclass 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 knightdouble TheKnights::single(int n, int a, int b) {//define directionsconst 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 knightsdouble TheKnights::inter(int n, int a, int b) {//define directionsconst 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!