Day5 题目做完,感觉银牌距离我近而遥远…
这套题五题稳银,而且这五题都不算难题,但是看看自己能不能一遍写成,这是有难度的…
A.Alice’s Print Service
买东西,买的越多越便宜,每次询问一个x,求买x件物品最便宜的价格(可以多买)
维护一个区间最小值
M
I
N
i
表
示
i
−
n
的
区
间
最
小
值
MIN_i表示i-n的区间最小值
MINi表示i−n的区间最小值,我们知道,我们可以多买,但是不能少买.设小于当前数量的标准为i,所以只需要比较
min
i
+
1
n
M
I
N
i
\min\limits_{i+1}^{n} MIN_i
i+1minnMINi与
(
x
−
s
[
i
]
)
∗
p
[
i
]
(x-s[i])*p[i]
(x−s[i])∗p[i],取较小的即可(查找i要用二分)
(其实这题开始想线段树RMQ的…)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+5;
ll jt[maxn],pri[maxn];
ll minn[maxn];
int n,m;
ll mymin(ll a,ll b){
return a<b?a:b;
}
int main()
{
int t;scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%lld%lld",&jt[i],&pri[i]);
}
ll mint=1e18+18;
for(int i=n;i>=1;--i) {
mint=mymin(mint,jt[i]*pri[i]);
minn[i]=mint;
}
minn[n+1]=1e18+18;
for(int i=1;i<=m;++i){
ll t;
scanf("%lld",&t);
int pos=upper_bound(jt+1,jt+1+n,t)-jt;
//cout<<pos<<endl;
printf("%lld\n",mymin(minn[pos],t*pri[pos-1]));
}
}
}
C.Collision
####简单几何
有一个奖章,半径为 R m R_m Rm,一个圆圈,半径为R,一个硬币,半径为r,其中奖章和圆圈是同心圆,圆心为(0,0),给定硬币的坐标 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)和初始x,y速度x,y,求硬币在圆圈内的时间(若和奖章发生碰撞,按弹性碰撞处理,速度不变)
先讨论下硬币会不会进入圆圈,不会就输出0.条件:
(1)
(
x
0
⃗
,
y
0
⃗
)
⋅
(
x
⃗
,
y
⃗
)
≥
0
(\vec{x_0},\vec{y_0})\cdot(\vec{x},\vec{y})\geq0
(x0,y0)⋅(x,y)≥0
(2)与圆心距离大于
(
R
m
+
r
)
(R_m+r)
(Rm+r)
其余写在注释
#include<bits/stdc++.h>
using namespace std;
double Rm,R,r,a,b,x0,y_;
void solve()
{
double v=a*a+b*b;v=sqrt(v);
double d,k;
double time;
if(a==0){
d=abs(x0);//别忘了绝对值,开始就wa在了这里
}
else {
double k=b/a;
double b0=y_-k*x0;
d=abs(b0/sqrt(k*k+1));//绝对值
}
if(d>R+r || a*x0+y_*b>=0){
printf("%.3f\n",0.0000);
return;
}else{
double q=(R+r)*(R+r)-d*d;q=sqrt(q);
if(d<Rm+r){
double q2=(Rm+r)*(Rm+r)-d*d;
q2=sqrt(q2);
double l=q-q2;
time=l*2/v;//碰撞后直接时间*2
}else{
time=q*2/v;//接触圆环的时间到经过垂直于轨迹的过原点的直线的时间*2
}
}
printf("%.3f\n",time);
}
int main()
{
while(cin>>Rm>>R>>r>>x0>>y_>>a>>b){
solve();
}
}
##H.Skycity
开始读错题…
####给建筑铺玻璃,问最少要多少玻璃,建筑是图中的一个个圆柱,玻璃是外面的切面.求玻璃最小面积是,(每块玻璃最小值是S(因为高度一定,所以相当于玻璃最小长度固定))
其实挺水的一道题,直接上代码
#include<bits/stdc++.h>
using namespace std;
double R,r,H,n,S;
double Ra[1200];
const double PI=acos(-1);
void solve(){
memset(Ra,0,sizeof(Ra));
for(int i=1;i<=n;++i){
Ra[i]=r+(R-r)/n*(i-1);根据样例,并没有包括最下面面积为R的一层
//cout<<Ra[i]<<" ";
}
double d=S*n/H/2;
double h=H/n;
double ans=0;
for(int i=1;i<=n;++i){
int x=PI/atan(d/Ra[i]);
ans+=2*h*x*Ra[i]*tan(PI/x);
}
printf("%.4f\n",ans);
}
int main()
{
//freopen("in","r",stdin);
while(cin>>R>>r>>H>>n>>S){
solve();
}
}
J.Josephina and RPG
这题还是比较简单的,就是题面有点长,dp一下就ok.注意输入的矩形边长是
C
n
3
C_n^3
Cn3,不是n,
还有注意对于一个敌人,他的编号是
I
D
[
i
]
,
不
是
i
ID[i],不是i
ID[i],不是i
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+4;
double dp[130][maxn],P[130][130];
int ai[maxn];
int main()
{
int n;
while(cin>>n){
n=n*(n-1)*(n-2)/6;
memset(dp,0,sizeof(dp));
memset(P,0,sizeof(P));
memset(ai,0,sizeof(ai));
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
cin>>P[i][j];
}
}
int N;cin>>N;
for(int i=0;i<130;++i) dp[i][0]=1;
for(int i=1;i<=N;++i) cin>>ai[i],++ai[i];
for(int j=0;j<N;++j){
for(int i=1;i<=n;++i){
dp[i][j+1]=max(dp[i][j+1],dp[i][j]*P[i][ai[j+1]]);//不交换
if(j>0)
dp[ai[j]][j+1]=max(dp[ai[j]][j+1],dp[i][j]*P[ai[j]][ai[j+1]]);//交换
}
}
double ans=0;
for(int i=1;i<=n;++i) ans=max(ans,dp[i][N]);
printf("%.7f\n",ans);
}
}
##K.Pocket Cube
####…魔方题,不多说了,细心就好(前面的省略号表示无语,无奈)
因为每次可以走6步,最多走7次,
6
7
=
279936
6^7=279936
67=279936,甚至不必判重,直接暴力dfs就好
#include<bits/stdc++.h>
using namespace std;
int n;
int a[24];
int T[6][24]={
{0,21,2,23,4,5,6,1,9,15,10,11,12,3,8,14,16,7,18,13,20,17,22,19},
{0,7,2,13,4,5,6,17,14,8,10,11,12,19,15,9,16,21,18,23,20,1,22,3},
{0,1,2,3,4,5,6,7,8,9,12,13,14,15,21,20,17,19,16,18,11,10,22,23},
{0,1,2,3,4,5,6,7,8,9,21,20,10,11,12,13,18,16,19,17,15,14,22,23},
{0,1,11,5,4,16,12,6,2,9,10,17,13,7,3,15,14,8,18,19,20,21,22,23},
{0,1,8,14,4,3,7,13,17,9,10,2,6,12,16,15,5,11,18,19,20,21,22,23}
};
int count(int t[24]){
int res=0;
if (t[0]==t[1] && t[1]==t[2] && t[2]==t[3]) res++;
if (t[8]==t[9] && t[14]==t[15] && t[8]==t[14]) res++;
if (t[6]==t[7] && t[7]==t[12] && t[12]==t[13]) res++;
if (t[4]==t[5] && t[5]==t[11] && t[11]==t[10]) res++;
if (t[16]==t[17] && t[17]==t[19] && t[19]==t[18]) res++;
if (t[20]==t[21] && t[21]==t[22] && t[22]==t[23]) res++;
return res;
}
int ans;
int cnt=0;
void dfs(int t[24],int step){
ans=max(ans,count(t));
if(step==n) return;
int tt[24];
for(int i=0;i<6;++i){
for(int j=0;j<24;++j){
tt[j]=t[T[i][j]];
}
dfs(tt,step+1);
}
}
int main()
{
//freopen("in","r",stdin);
while(cin>>n){
for(int i=0;i<24;++i) cin>>a[i];
ans=0;
dfs(a,0);
cout<<ans<<endl;
}
}