1、题目名称:圆小艺
最近小艺酱渐渐变成了一个圆滑的形状-球!! 小艺酱开始变得喜欢上球! 小艺酱得到n个同心圆。 小艺酱对着n个同心圆 进行染色。 相邻的圆范围内不能有相同的颜色。相隔一层的圆颜色相同。 小艺酱想知道两种颜色中最外层圆的那种颜色总 共染了多少?
分析 :
这题似乎在以前的比赛中有出现过,这里就直接照搬以前的题解了。
圆环面积公式
S
=
π
(
R
2
−
r
2
)
,
R
>
r
S=\pi(R^2-r^2),R>r
S=π(R2−r2),R>r
先按半径大小排序
奇数层染一种颜色,偶数层染一种
最后根据n的奇偶性输出
注意精度问题
当然要精准的可以
π
=
arccos
(
−
1
)
\pi=\arccos(-1)
π=arccos(−1)
扩展
x
&
1
x \& 1
x&1表示取二进制最后一位,若
x
&
1
=
1
x\&1=1
x&1=1表示其为奇数,
等同于
x
m
o
d
2
=
1
x\mod 2 =1
xmod2=1
#include<bits/stdc++.h>
using namespace std;
const double pie = 3.1415926535897932846;
double a[11000],s1,s2;
int main(){
int n; cin >> n;
for(int i=1;i<=n;i++) cin >> a[i];
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
if(i & 1) s1 += pie*(a[i]*a[i]-a[i-1]*a[i-1]);
else s2 += pie*(a[i]*a[i]-a[i-1]*a[i-1]);
if(n&1) printf("%.3lf",s1);
else printf("%.3lf",s2);
return 0;
}
2、题目名称:近视的小张
小张和他的 M 个朋友来到了一个十分神奇的地方,在这里有 N 个 柱子, 对于每个 1 <= i <= N, 第 i 个柱子都有两个
属性 : H[i], P[i]。
H[i] 表示柱子 i 的高度, 而 P[i] 则表示柱子 i 当前所处的位置,题目保证同一个位置不会有多个柱子。
在一个柱子 i 在另一个不比他低的柱子 j 的后面时 (P[i] > P[j] && H[i] <= H[j]), 这个柱子会被遮挡住, 也就不再能被
清晰的看到。
小张和他的朋友们在位置 0 休息时, 发现似乎朋友们能清晰看到的柱子数量并不相同,在他反复思考后, 他认为这可能
是近视度数导致的,于是他询问了每一个朋友的近视度数 A[i]。
为了方便计算, 我们认为对于朋友 j 来说,对每一个柱子 i, 如果有 P[i] > A[j], 那么第 i 个柱子无法被清晰看见。
请你计算出每个小张的朋友能清晰看到的最远一个柱子的位置, 如果那个朋友一个柱子都没有清晰看到, 请输出 -1。
分析
这题我只有80分,但找不出哪有问题,就给大家说一下我的思路,如果有哪位大佬能指出我代码的漏洞,可在评论区留言,谢谢。
我先将每根柱子按距离从小到大排序,然后构造一个单调队列使这些柱子的高度单调递增,即预处理出满足条件的柱子。
然后就是找到每个人能看到的最远的柱子,其实就是在一些柱子的距离{
P
n
P_n
Pn}中,给定一个数
A
A
A,找到满足
P
i
≤
A
P_i \le A
Pi≤A的最大
P
i
P_i
Pi。
很快就能想到两种思路,因为{
P
n
P_n
Pn}经过刚才的处理是单调递增的,所以可以用二分查找;另一种思路则是将{
A
n
A_n
An}排序,然后用双指针。两种方法我都写在代码中,都是80分。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+10;
ll n,m;
ll ans[N];
ll q[N],tail;
struct node{
ll h,p;
}l[N];
bool cmp1(node x,node y){
return x.p < y.p;
}
struct stu{
ll a,id;
}s[N];
bool cmp2(stu x,stu y){
return x.a < y.a;
}
int main(){
cin >> m >> n;
for(int i=1;i<=n;i++) cin >> l[i].h;
for(int i=1;i<=n;i++) cin >> l[i].p;
for(int i=1;i<=m;i++){
cin >> s[i].a;
s[i].id = i;
}
sort(l+1,l+1+n,cmp1);
ll lst = 0;
for(int i=1;i<=n;i++)
if(l[i].h >= l[lst].h) q[++tail] = l[i].p,lst = i;
sort(s+1,s+1+m,cmp2);
for(int i=1,j=1;i<=m;i++){
if(q[j] <= s[i].a) ans[s[i].id] = q[j];
else ans[s[i].id] = -1;
while(q[j+1] <= s[i].a && j<tail)
ans[s[i].id] = q[++j];
}//双指针
/*for(int i=1;i<=m;i++){
int l=1,r=tail,mid;
while(l < r){
mid = (l+r+1)/2;
if(q[mid] <= a[i]) l = mid;
else r = mid-1;
}
if(q[l] <= a[i]) ans[i] = q[l];
else ans[i] = q[l-1];
if(ans[i] == 0) ans[i] = -1;
}*///二分查找
for(int i=1;i<=m;i++)
cout << ans[i] << "\n";
return 0;
}
3、题目名称:小股炒股
已知n天后的股票行情,现在已有的本金是m, 规定只能入手一次股票和抛售一次股票。 最大收益(含本金)是?
分析
没什么好说的,因为只能入手和抛售一次,所以从后往前枚举求出最大的一天的股票,然后模拟求最值,具体可以看代码。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int p[1010];
int n,m;
int main(){
cin >> n >> m;
for(int i=1;i<=n;i++) cin >> p[i];
int maxn = 0,ans = 0;
for(int i=n;i>=1;i--){
maxn = max(maxn,p[i]);
ans = max(ans,m+(maxn-p[i])*(m/p[i]));
}
cout << ans;
return 0;
}
4、题目名称:买铅笔
P老师需要去商店买n支铅笔作为小朋友们参加编程比赛的礼物。她发现商店一共有 3 种包装的铅笔,不同包装内的铅笔数
量有可能不同,价格也有可能不同。为了公平起 见,P老师决定只买同一种包装的铅笔。 商店不允许将铅笔的包装拆开,
因此P老师可能需要购买超过 n 支铅笔才够给小朋 友们发礼物。 现在P老师想知道,在商店每种包装的数量都足够的情况
下,要买够至少 n 支铅笔最少需要花费多少钱。
分析
小学生数学题,三种的金额都算一下然后取最小值就行了。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,ans = 9999999;
int a[4],b[4];
int main(){
cin >> n;
for(int i=1;i<=3;i++){
cin >> a[i] >> b[i];
ans = min(ans,int(ceil(n*1.0/a[i])*b[i]));
}
cout << ans;
return 0;
}