您的位置:首页 > Web前端 > AngularJS

tc 146 2 RectangularGrid(数学推导)

2015-06-11 14:27 621 查看

SRM 146 2 500RectangularGrid

Problem Statement

Given the width and height of a rectangular grid, return the total number of rectangles (NOT counting squares) that can be found on this grid.

For example, width = 3, height = 3 (see diagram below):

__ __ __
|__|__|__|
|__|__|__|
|__|__|__|

In this grid, there are 4 2x3 rectangles, 6 1x3 rectangles and 12 1x2 rectangles. Thus there is a total of 4 + 6 + 12 = 22 rectangles. Note we don't count 1x1, 2x2 and 3x3 rectangles because they are squares.

Definition

ClassRectangularGrid

MethodcountRectangles

Parametersint , int

Returnslong long

Method signaturelong long countRectangles(int width, int height)

(be sure your method is public)

Limits

Time limit (s)2.000

Memory limit (MB)64

Notes

rectangles with equals sides (squares) should not be counted.

Constraints

width and height will be between 1 and 1000 inclusive.

Test cases

width3

height3

Returns22

See above

width5

height2

Returns31

__ __ __ __ __
|__|__|__|__|__|
|__|__|__|__|__|

In this grid, there is one 2x5 rectangle, 2 2x4 rectangles, 2 1x5 rectangles, 3 2x3 rectangles, 4 1x4 rectangles, 6 1x3 rectangles and 13 1x2 rectangles. Thus there is a total of 1 + 2 + 2 + 3 + 4 + 6 + 13 = 31 rectangles.

width10

height10

Returns2640

width1

height1

Returns0

width592

height964

Returns81508708664

#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <typeinfo>
#include <fstream>

using namespace std;
typedef long long ll ;
class RectangularGrid {
public:
long long countRectangles(int l , int r) {
if (l > r) swap (l , r ) ;
//  printf ("l = %d , r = %d\n" , l , r ) ;
ll all = (1ll *l*l*r*r + 1ll *l*r*r + 1ll *r*l*l + 1ll *r*l) / 4 ;
ll sum = 1ll * l * (l - 1) * (l + 1) / 3 + 1ll * (r - l + 1) * l * (l + 1) / 2 ;
//   printf ("all = %lld , sum = %lld\n" , all , sum) ;
return all - sum ;
}
};

// CUT begin
ifstream data("RectangularGrid.sample");

string next_line() {
string s;
getline(data, s);
return s;
}

template <typename T> void from_stream(T &t) {
stringstream ss(next_line());
ss >> t;
}

void from_stream(string &s) {
s = next_line();
}

template <typename T>
string to_string(T t) {
stringstream s;
s << t;
return s.str();
}

string to_string(string t) {
return "\"" + t + "\"";
}

bool do_test(int width, int height, long long __expected) {
time_t startClock = clock();
RectangularGrid *instance = new RectangularGrid();
long long __result = instance->countRectangles(width, height);
double elapsed = (double)(clock() - startClock) / CLOCKS_PER_SEC;
delete instance;

if (__result == __expected) {
cout << "PASSED!" << " (" << elapsed << " seconds)" << endl;
return true;
}
else {
cout << "FAILED!" << " (" << elapsed << " seconds)" << endl;
cout << "           Expected: " << to_string(__expected) << endl;
cout << "           Received: " << to_string(__result) << endl;
return false;
}
}

int run_test(bool mainProcess, const set<int> &case_set, const string command) {
int cases = 0, passed = 0;
while (true) {
if (next_line().find("--") != 0)
break;
int width;
from_stream(width);
int height;
from_stream(height);
next_line();
long long __answer;
from_stream(__answer);

cases++;
if (case_set.size() > 0 && case_set.find(cases - 1) == case_set.end())
continue;

cout << "  Testcase #" << cases - 1 << " ... ";
if ( do_test(width, height, __answer)) {
passed++;
}
}
if (mainProcess) {
cout << endl << "Passed : " << passed << "/" << cases << " cases" << endl;
int T = time(NULL) - 1433920510;
double PT = T / 60.0, TT = 75.0;
cout << "Time   : " << T / 60 << " minutes " << T % 60 << " secs" << endl;
cout << "Score  : " << 500 * (0.3 + (0.7 * TT * TT) / (10.0 * PT * PT + TT * TT)) << " points" << endl;
}
return 0;
}

int main(int argc, char *argv[]) {
cout.setf(ios::fixed, ios::floatfield);
cout.precision(2);
set<int> cases;
bool mainProcess = true;
for (int i = 1; i < argc; ++i) {
if ( string(argv[i]) == "-") {
mainProcess = false;
} else {
cases.insert(atoi(argv[i]));
}
}
if (mainProcess) {
cout << "RectangularGrid (500 Points)" << endl << endl;
}
return run_test(mainProcess, cases, argv[0]);
}
// CUT end


View Code
已知一个长 l , 宽 r 的由1×1的单位矩阵构成的矩阵,问其中有多少个长方形?

那么我们只要求出其中矩阵的总个数n , 和正方形数m,然后n - m就是答案。

n= l*r + l×(r×(r-1))/2 + r×(l×(l-1))/2 + l×r×(l-1)×(r-1)/4

 =(l×l×r×r+l×r×r+r×l×l+r×l)/4;

m=2×(1+2×3/2+4×3/2+……+l×(l-1)/2) + (r-l+1)×l×(l+1)/2;

 =l×(l+1)×(2×l+1)/6 + (r-l)×l×(l+1)/2;

PS:

1^2 + 2^2 + 3^2 + 4^2 + 5^2 +……+n^2 = n*(n + 1)*(2*n+1)/6;

证明:(来自百度文库)

想像一个有圆圈构成的正三角形,

第一行1个圈,圈内的数字为1

第二行2个圈,圈内的数字都为2,

以此类推

第n行n个圈,圈内的数字都为n,

我们要求的平方和,

就转化为了求这个三角形所有圈内数字的和。

设这个数为r

下面将这个三角形顺时针旋转120度,

得到第二个三角形

再将第二个三角形顺时针旋转120度,得到第三个三角形.

然后,将这三个三角形对应的圆圈内的数字相加,

我们神奇的发现所有圈内的数字都变成了

2n+1

而总共有几个圈呢,这是一个简单的等差数列求和

1+2+……+n=n(n+1)/2

于是

3r=[n(n+1)/2]*(2n+1)

r=n(n+1)(2n+1)/6
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: