百度
1.买帽子
商场里有n顶帽子,有些帽子的价格可能相同,度度想买一顶价格第三便宜的帽子,求第三便宜的帽子的价格是多少?
输入:输入一个正整数,接下来输入N个数表示每顶帽子的价格
如果存在第三便宜的帽子,请问这个价格是多少?
思路:用set来装帽子的价格,将第三便宜的输出
#include<set>
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int num[50];
set<int>s;
for(int i=0; i<n; ++i)
{
int val;
cin>>val;
s.insert(val);
}
int count = 0;
set<int>::iterator it = s.begin();
while(it != s.end())
{
count++;
if(count == 3)
{
break;
}
++it;
}
cout<<*it<<endl;
}
2.度度熊回家
一个数轴上有N个点,第一个点的坐标是度度熊现在的位置,第N-1个点是度度熊家的位置,现在,他需要依次从0坐标走到N-1坐标,但是除了0和N-1坐标以外,它可以在其余的N-2个坐标中选出一个点,并将这个点直接忽略掉,问嘟嘟熊回家至少要走多少距离
输入:正整数N
接下来输入N个整数表示坐标,正数表示X轴的正方向,负数表示X轴的负方向,
输出:输出一个整数表示最少需要走的距离
算法思想:暴力枚举
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int a[50];
for(int i=0; i<n; ++i)
{
cin>>a[i];
}
int ans = 100000;
for(int i=0; i<n; ++i)
{
int res = 0;
int last = a[0];
for(int j=1; j<n-1; ++j)
{
if(i==j)
continue;
res+=abs(a[j]-last);
last = a[j];
}
res+=abs(a[n-1]-last);
ans = min(res, ans);
}
cout<<ans<<endl;
}
3.寻找三角形
三维空间中有N个点,每个点可能是三种颜色其中的一种,三种颜色分别是红,绿,蓝,分别用“R”“G””B”表示
现在要找出三个点,共组成一个三角形,使得这个三角形的面积最大
但是三角形必须满足,三个点的颜色要么全部相同,要么全部不同
输入:首先输入一个正整数N,三维坐标系内点的个数
输入N行,每一行输入c x y z c为“R””G””B”的其中一个,x,y,z是该点的坐标
输出:一个数表示三角形的面积,保留5位小数
(1) 向量的向量积
两个向量a和b的叉积(向量积)可以被定义为:
在这里θ表示两向量之间的角夹角(0° ≤ θ ≤ 180°),它位于这两个矢量 所定义的平面上。
向量积的模(长度)可以解释成以a和b为邻边的平行四边形的面积。求三角形ABC的面积,根据向量积的意义,得到:
1.用叉积求三角形面积的公式
a=axi+ayj+azk;
b=bxi+byj+bzk;
a×b=(aybz-azby)i+(azbx-axbz)j+(axby-aybx)k,为了帮助记忆,利用三阶行列式,写成:
2.用海伦公式求三角形的面积公式
海伦公式:只要已知三角形的三条边长,就可以求三角形的面积.
公式:若已知三角形的三条边长分别为a、b、c
,S=根号下p(p-a)(p-b)(p-c)
(p为三角形周长的一半,即p=1/2(a+b+c))
本题的思路:也是用暴力枚举,列出所有的可能
#include<iostream>
using namespace std;
#define mul(x) ((x)*(x))
char type[50];
double x[50], y[50], z[50];
int main()
{
int n;
cin>>n;
for(int i=0; i<n; ++i)
{
cin>>type[i]>>x[i]>>y[i]>>z[i];
}
double ans = 0.0;
for(int i=0; i<n; ++i)
{
for(int j=0; j<i; ++j)
{
for(int k=0; k<j; ++k)
{
int ok = 0;
if((type[i] == type[j])&&(type[i] == type[k]))
ok = 1;
if(type[i] != type[j] && (type[i] != type[k]) && (type[j] != type[k]))
ok = 1;
if(!ok)
continue;
double ax = x[j]-x[i], ay = y[j]-y[i], az = z[j] - z[i];
double bx = x[k] - x[i], by = y[k] - y[i], bz = z[k]-z[i];
double res = sqrt(mul(ay*bz - az*by) + mul(az*bx - ax*bz) + mul(ax*by-ay*bx));
ans = ans > res*0.5 ? ans:res*0.5;
}
}
}
printf("%.5lf\n", ans);
}
4.有趣的排序
度度熊有一个N个数的数组,它想将数组从小到大排好序,但是只会以下操作
任取数组中的一个数然后把它放置在数组的最后一个位置
问最少需要操作多少次能使数组从小到大有序?
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int n;
int num[50];
int solve(vector<int> a)
{
vector<int> b;
b = a;
sort(b.begin(), b.end());
int pos = 0, n = a.size();
for(int i=0; i<n; ++i)
{
if(a[i] == b[pos])
pos++;
if(pos == n)
break;
}
return n-pos;
}
int main()
{
cin>>n;
vector<int>v;
for(int i=0; i<n; ++i)
{
cin>>num[i];
int value = num[i];
v.push_back(value);
}
cout<<solve(v)<<endl;
}
5.不等式数列
度度熊最近对全排列特别感兴趣,对于1到n的一个排列,度度熊发现可以在中间根据大小关系插入合适的大于或者小于符号,使其成为一个合法的不等式数列,现在度度熊手中有k个小于符号和n-k-1个大于符号,度度熊想知道对于1至n 任意的排列中有多少个可以使用这些符号使其成为合法的不等式数列
输入:包含一行,包含两个整数n和k
输出:满足条件的排列数,答案对2017取模
dp[i][j] = dp[i - 1][j - 1] * (i - j) + dp[i - 1][j] * (j + 1)
#include<iostream>
using namespace std;
int n, k;
int dp[1005][1005];
int main()
{
int n, k;
cin>>n>>k;
for(int i=1; i<=n; ++i)
{
dp[i][0] = 1;
}
for(int i=2; i<=n; ++i)
{
for(int j=1; j<=k; ++j)
dp[i][j] = (dp[i-1][j-1]*(i-j) + dp[i-1][j]*(j+1))%2017;
}
cout<<dp[n][k]%2017;
}