百度2017實習程式設計題
[程式設計題] 尋找三角形
時間限制:1秒
空間限制:32768K
三維空間中有N個點,每個點可能是三種顏色的其中之一,三種顏色分別是紅綠藍,分別用’R’, ‘G’, ‘B’表示。
現在要找出三個點,並組成一個三角形,使得這個三角形的面積最大。
但是三角形必須滿足:三個點的顏色要麼全部相同,要麼全部不同。
輸入描述:
首先輸入一個正整數N三維座標系內的點的個數.(N <= 50)
接下來N行,每一行輸入 c x y z,c為’R’, ‘G’, ‘B’ 的其中一個。x,y,z是該點的座標。(座標均是0到999之間的整數)
輸出描述:
輸出一個數表示最大的三角形面積,保留5位小數。
輸入例子:
5
R 0 0 0
R 0 4 0
R 0 0 3
G 92 14 7
G 12 16 8
輸出例子:
6.00000
暴力計算,窮舉
#include <iostream>
#include <vector>
#include <stdio.h>
#include <algorithm>
#include <map>
#include <string>
#include <limits.h>
#include <cmath>
#include <iomanip>
using namespace std;
double Area(double a,double b,double c)
{
double s = (a + b + c) / 2;
return sqrt(s*(s - a)*(s - b)*(s - c));
}
double CountTri(vector<vector<int>> vec)
{
int len = vec.size();
if (len < 3)
return 0;
double min = 0;
for (int i = 0; i < len; ++i)
{
for (int j = i + 1; j < len; ++j)
{
for (int k = j + 1; k < len; ++k)
{
double a = pow(vec[i][0] - vec[j][0], 2) + pow(vec[i][1] - vec[j][1], 2) + pow(vec[i][2] - vec[j][2], 2);
double b = pow(vec[i][0] - vec[k][0], 2) + pow(vec[i][1] - vec[k][1], 2) + pow(vec[i][2] - vec[k][2], 2);
double c= pow(vec[j][0] - vec[k][0], 2) + pow(vec[j][1] - vec[k][1], 2) + pow(vec[j][2] - vec[k][2], 2);
double temp = Area(sqrt(a),sqrt(b), sqrt(c));
if (temp > min)
min = temp;
}
}
}
return min;
}
int main()
{
int count;
cin >> count;
vector<vector<int>> R;
vector<vector<int>> G;
vector<vector<int>> B;
while (count--)
{
string str;
cin >> str;
if (str == "R")
{
int x;
vector<int> temp;
for (int i = 0; i <= 2; ++i){
cin >> x;
temp.push_back(x);
}
R.push_back(temp);
}
if (str == "G")
{
int x;
vector<int> temp;
for (int i = 0; i <= 2; ++i){
cin >> x;
temp.push_back(x);
}
G.push_back(temp);
}
if (str == "B")
{
int x;
vector<int> temp;
for (int i = 0; i <= 2; ++i){
cin >> x;
temp.push_back(x);
}
B.push_back(temp);
}
}
double Rmax = CountTri(R);
double Gmax = CountTri(G);
double Bmax = CountTri(B);
double sum = 0;
for (int i = 0; i < R.size(); ++i){
for (int j = 0; j < G.size(); ++j)
{
for (int k = 0; k < B.size(); ++k)
{
vector<vector<int>> temp;
temp.push_back(R[i]);
temp.push_back(G[j]);
temp.push_back(B[k]);
double area = CountTri(temp);
if (area > sum)
sum = area;
}
}
}
double res=max(max(Rmax, Gmax), max(Bmax, sum));
cout << fixed << setprecision(5) << res << endl;
return 0;
}
[程式設計題] 不等式數列
時間限制:1秒
空間限制:32768K
度度熊最近對全排列特別感興趣,對於1到n的一個排列,度度熊發現可以在中間根據大小關係插入合適的大於和小於符號(即 ‘>’ 和 ‘<’ )使其成為一個合法的不等式數列。但是現在度度熊手中只有k個小於符號即(‘<”)和n-k-1個大於符號(即’>’),度度熊想知道對於1至n任意的排列中有多少個排列可以使用這些符號使其為合法的不等式數列。
輸入描述:
輸入包括一行,包含兩個整數n和k(k < n ≤ 1000)
輸出描述:
輸出滿足條件的排列數,答案對2017取模。
輸入例子:
5 2
輸出例子:
66
動態規劃 對於從1-n,k個小於號的合法組合數記為dp[n][k],假設已經知道dp[n-1][k],那麼一定是在1-n-1,k個小於號組成的排列中增加一個大於號和n,那麼一定是新增在有小於號的空當中以及行首,每種排列有(k+1)中放的位置,或者是dp[n-1][k-1],也就是說要把n和一個小於號放在1-n-1的合法序列中,這一定是放到有大於號的位置中以及最後,這就包括n-k中情況,所以可以得到遞推式:
dp[n][k]=dp[n-1][k](k+1)+dp[n-1][k-1](n-k);
之後直接利用動態規劃的方法遞推即可.程式碼比較簡單
#include <iostream>
#include <vector>
#include <stdio.h>
#include <algorithm>
#include <map>
#include <limits.h>
using namespace std;
int main()
{
int n, k;
cin >> n >> k;
vector<vector<int>> dp(n + 1, vector<int>(n+1, 0));
dp[2][0] = 1;
dp[2][1] = 1;
for (int i = 3; i <= n; ++i)
{
dp[i][0] = 1;
dp[i][i - 1] = 1;
}
for (int i = 3; i <= n; ++i){
for (int j = 1; j <= i - 2; ++j)
{
dp[i][j] = (dp[i - 1][j - 1] *(i - j))%2017 + (dp[i - 1][j] *(j + 1))%2017;
}
}
cout << dp[n][k]%2017 << endl;
return 0;
}