前言
一个破计算器能搞出一堆幺蛾子,只能说博主就是个fw。
不管了,所有博主没法处理的就都是不合法操作。博主写了半天就只有一个东西是绝对没有bug的——遇到错误时的处理系统。
既然不想被人看到错误,那就干脆让别人一直都能看到你正确的那部分。
这套题的题目真的是让Jo厨狂喜啊,high到不行。
The Fool(规律)
比赛链接:https://acm.dingbacode.com/showproblem.php?pid=6555
题目大意
请求出
∑
i
N
[
n
i
]
\sum_{i}^{N}[\frac{n}{i}]
∑iN[in]的奇偶性,其中[x]为向下取整。
思路
伊奇真的好喜欢波波啊呜呜呜┭┮﹏┭┮
打表找规律,最后会发现这个值的奇偶性与其开方值的奇偶性相同。
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
int main()
{
int t;
int cnt=0;
cin>>t;
while(t--){
cout<<"Case "<<(++cnt)<<": ";
int n;
cin>>n;
n=int(sqrt(n));
if(n&1) cout<<"odd"<<endl;
else cout<<"even"<<endl;
}
}
The World(思维)
比赛链接:https://acm.dingbacode.com/showproblem.php?pid=6556
题目大意
由于各地所属的时区不同,在旅游的过程中算出目的地的地方时显得尤为重要。
现给出四座城市的名称与其地方时的信息:
- 北京(Beijing),中国首都,地方时为UTC(世界标准时间)+8;
- 华盛顿(Washington),美国首都,地方时为UTC(世界标准时间)-5;
- 伦敦(London),英国首都,地方时为UTC(世界标准时间);
- 莫斯科(Moscow),俄罗斯首都,地方时为UTC(世界标准时间)+3;
接下来会给出一个时间:XX:XX AM/PM,紧接着给出两个城市的名称A、B。
如果A城市的地方时为XX:XX AM/PM,请问:
城市B的地方时是多少?
城市B相对于城市A是昨天(Yesterday)/今天(Today)/(明天)Tomorrow?
按格式输出"Yesterday/Today/Tomorrow hour:minute AM/PM"。
思路
塑料的『The World』,铁打的『Lovers』。
很简单的一道题,先把A的地方时换算成世界标准时间,然后再换算成B的地方时,中间过程记录是哪一天即可。
不过这题还是挺坑的,它的时间是这样的:
注意一下即可。
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
map<string,int> mp;
void init()
{
mp.clear();
mp["Beijing"]=8;
mp["Washington"]=-5;
mp["Moscow"]=3;
mp["London"]=0;
}
int main()
{
int t;
init();
int cnt=0;
cin>>t;
while(t--){
string time,noon;
string p1,p2;
cin>>time>>noon;
cin>>p1>>p2;
int flag=0,h=0,pos=0;
for(;;pos++){
if(time[pos]==':') break;
h=h*10+time[pos]-'0';
}
if(noon=="PM"&&h!=12) h+=12;
if(noon=="AM"&&h==12) h=0;
h=h-mp[p1]+mp[p2];
if(h<0){
flag=-1;
h=24+h;
}
else if(h>=24){
flag=1;
h=h-24;
}
if(h==0) h=12,noon="AM";
else if(h<=11) noon="AM";
else if(h==12) noon="PM";
else h-=12,noon="PM";
cout<<"Case "<<(++cnt)<<": ";
if(flag==-1) cout<<"Yesterday ";
else if(flag==1) cout<<"Tomorrow ";
else cout<<"Today ";
cout<<h<<time.substr(pos)<<" "<<noon<<endl;
}
}
The Tower(计算几何)
比赛链接:https://acm.dingbacode.com/showproblem.php?pid=6559
题目大意
在三维坐标轴上存在一个圆锥。底部圆的圆心为
(
0
,
0
,
0
)
(0,0,0)
(0,0,0),半径为
r
r
r,圆锥高为
h
h
h。
现在有一个处于
(
x
0
,
y
0
,
z
0
)
(x_0,y_0,z_0)
(x0,y0,z0)的点以
(
v
x
,
v
y
,
v
z
)
(v_x,v_y,v_z)
(vx,vy,vz)的速度运动着。
请问这个点什么时候会撞到圆锥,输出碰撞时间。
思路
最近对这种几何题尤其的上瘾,所以当我看完题目之后整个人都是赛高泥high铁鸭子哒(bushi)。
首先我们假设点
(
x
0
,
y
0
,
z
0
)
(x_0,y_0,z_0)
(x0,y0,z0)与圆锥相撞于点
(
x
,
y
,
z
)
(x,y,z)
(x,y,z),那么就有:
{
x
=
x
0
+
v
x
t
y
=
y
0
+
v
y
t
z
=
z
0
+
v
z
t
\left\{\begin{matrix} x=x_0+v_xt\\ y=y_0+v_yt\\ z=z_0+v_zt\\ \end{matrix}\right.
⎩⎨⎧x=x0+vxty=y0+vytz=z0+vzt。
接下来取圆锥的纵截面:
由图可知(相似三角形):
x
2
+
z
2
r
=
x
2
+
y
2
+
(
z
−
h
)
2
r
2
+
h
2
\frac{\sqrt{x^2+z^2}}{r}=\frac{\sqrt{x^2+y^2+(z-h)^2}}{\sqrt{r^2+h^2}}
rx2+z2=r2+h2x2+y2+(z−h)2。
等式两边同时平方:
x
2
+
z
2
r
2
=
x
2
+
y
2
+
(
z
−
h
)
2
r
2
+
h
2
\frac{x^2+z^2}{r^2}=\frac{x^2+y^2+(z-h)^2}{r^2+h^2}
r2x2+z2=r2+h2x2+y2+(z−h)2。
联立方程组得:
{
x
=
x
0
+
v
x
t
y
=
y
0
+
v
y
t
z
=
z
0
+
v
z
t
x
2
+
z
2
r
2
=
x
2
+
y
2
+
(
z
−
h
)
2
r
2
+
h
2
\left\{\begin{matrix} x=x_0+v_xt\\ y=y_0+v_yt\\ z=z_0+v_zt\\ \frac{x^2+z^2}{r^2}=\frac{x^2+y^2+(z-h)^2}{r^2+h^2}\\ \end{matrix}\right.
⎩⎪⎪⎨⎪⎪⎧x=x0+vxty=y0+vytz=z0+vztr2x2+z2=r2+h2x2+y2+(z−h)2
所有的字母中只有 t t t是未知量,接下来我们就需要开始苦逼的化简过程了。
在博主薅了
20
20
20分钟头发(也许不是头发)之后终于给它化简出来了:
[
h
2
(
v
x
+
v
y
)
2
−
r
2
v
z
2
−
2
h
2
v
x
v
y
]
t
2
[h^2(v_x+v_y)^2-r^2v_z^2-2h^2v_xv_y]t^2
[h2(vx+vy)2−r2vz2−2h2vxvy]t2
+
+
+
[
2
h
2
(
v
x
+
v
y
)
(
x
0
+
y
0
)
−
2
r
2
v
z
(
z
0
−
h
)
−
(
2
h
2
x
0
v
y
+
2
h
2
y
0
v
x
)
]
t
[2h^2(v_x+v_y)(x_0+y_0)-2r^2v_z(z_0-h)-(2h^2x_0v_y+2h^2y_0v_x)]t
[2h2(vx+vy)(x0+y0)−2r2vz(z0−h)−(2h2x0vy+2h2y0vx)]t
+
+
+
[
h
2
(
x
0
+
y
0
)
2
−
r
2
(
z
0
−
h
)
2
−
2
h
2
x
0
y
0
]
[h^2(x_0+y_0)^2-r^2(z_0-h)^2-2h^2x_0y_0]
[h2(x0+y0)2−r2(z0−h)2−2h2x0y0]
=
=
0
==0
==0
(这要是没求对估摸着我当时就直接脑溢血爬不出机房了)
这就变成了一个简 单的一元二次方程式了: { a = h 2 ( v x + v y ) 2 − r 2 v z 2 − 2 h 2 v x v y b = 2 h 2 ( v x + v y ) ( x 0 + y 0 ) − 2 r 2 v z ( z 0 − h ) − ( 2 h 2 x 0 v y + 2 h 2 y 0 v x ) c = h 2 ( x 0 + y 0 ) 2 − r 2 ( z 0 − h ) 2 − 2 h 2 x 0 y 0 \left\{\begin{matrix} a=h^2(v_x+v_y)^2-r^2v_z^2-2h^2v_xv_y\\ b=2h^2(v_x+v_y)(x_0+y_0)-2r^2v_z(z_0-h)-(2h^2x_0v_y+2h^2y_0v_x)\\ c=h^2(x_0+y_0)^2-r^2(z_0-h)^2-2h^2x_0y_0\\ \end{matrix}\right. ⎩⎨⎧a=h2(vx+vy)2−r2vz2−2h2vxvyb=2h2(vx+vy)(x0+y0)−2r2vz(z0−h)−(2h2x0vy+2h2y0vx)c=h2(x0+y0)2−r2(z0−h)2−2h2x0y0
这样就可以求出两个 t t t值,接下来只需要判断 t t t值是否合理,合理的话取最小值即可。
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
double r,h,x,y,z,vx,vy,vz;
bool judge(double t)
{
double x_z=x+t*vx;
double y_z=y+t*vy;
double z_z=z+t*vz;
if(z_z>=0&&z_z<=h&&x_z*x_z+y_z*y_z<=r*r)
return true;
else return false;
}
int main()
{
int t,cnt=0;
scanf("%d",&t);
while(t--){
//11
scanf("%lf%lf",&r,&h);
scanf("%lf%lf%lf%lf%lf%lf",&x,&y,&z,&vx,&vy,&vz);
double a,b,c;
a=h*h*(vx+vy)*(vx+vy)-r*r*vz*vz-2*h*h*vx*vy;
b=2*h*h*(vx+vy)*(x+y)-2*r*r*vz*(z-h)-(2*h*h*x*vy+2*h*h*y*vx);
c=h*h*(x+y)*(x+y)-r*r*(z-h)*(z-h)-2*h*h*x*y;
double t1=(-b+sqrt(b*b-4*a*c))/(2.0*a);
double t2=(-b-sqrt(b*b-4*a*c))/(2.0*a);
double ans=inf;
if(judge(t1)) ans=min(ans,t1);
if(judge(t2)) ans=min(ans,t2);
printf("Case %d: %.10f\n",++cnt,ans);
}
}
几何题做起来是真的太上头了。
Strength(贪心)
比赛链接:https://acm.dingbacode.com/showproblem.php?pid=6563
题目大意
(找了半天没找到色猩猩对应的那一帧,就乎着看吧)
现在
A
l
i
c
e
Alice
Alice有
n
n
n个小兵,每个小兵的攻击力为
a
i
a_i
ai。
B
o
b
Bob
Bob有
m
m
m个小兵,每个小兵的攻击力为
b
i
b_i
bi。
当 A A A小兵(攻击力为 x x x)进攻 B B B小兵(攻击力为 y y y)的时候会出现以下情况:
- B B B小兵处于防御姿态, x < y x<y x<y。 => A A A小兵死亡, B B B小兵毫发无伤;
- B B B小兵处于防御姿态, x > = y x>=y x>=y。 => A A A小兵死亡,B小兵死亡;
- B B B小兵处于进攻姿态, x < y x<y x<y。=> A A A小兵死亡, B B B小兵毫发无伤, A A A小兵的主人受到 y − x y-x y−x点伤害;
- B B B小兵处于进攻姿态, x > = y x>=y x>=y。=> A A A小兵死亡, B B B小兵死亡, B B B小兵的主人受到 x − y x-y x−y点伤害;
一旦主人没有小兵可以用的时候,对方接下来的进攻都会直接对主人造成伤害。
一开始所有的小兵都是进攻姿态。
接下来是
A
l
i
c
e
Alice
Alice的进攻时间,
B
o
b
Bob
Bob把他手下的一部分小兵改为防御姿态。
请问
A
l
i
c
e
Alice
Alice最多可以对
B
o
b
Bob
Bob造成多少伤害?
思路
贪心,分情况讨论。
一.只揍Bob的进攻姿态小兵。
如果我们打防御姿态的小兵,就算打赢了,也不会对
B
o
b
Bob
Bob造成伤害,还会废掉我们的一个小兵,不是很划得来。
所以我们把主力全部用在打
B
o
b
Bob
Bob的进攻姿态小兵上面,贪出最大伤害值。
二.杀掉Bob所有的兵。
如果我们有能力把Bob的兵全部干掉,这样我们剩下的兵就可以造成真实伤害,是有可能造成一个很高的伤害值的。
这样的话我们就要考虑如何处理Bob的防御兵了。我们要尽可能地用和其防御兵攻击力差不多的兵来完成自爆行动,这样的话最佳的处理方式就是lower_bound
。
但一个兵只能用一次,所以还要记录一下自己哪些兵是在清理Bob所有的兵时所用的。
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
struct node
{
int x,y;
}b[maxn];
int a[maxn];
bool vis[maxn];
bool cmp(node z,node c)
{
if(z.y!=c.y)
return z.y<c.y;
else
return z.x<c.x;
}
int main()
{
int t,cnt=0;
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i],vis[i]=false;
for(int i=1;i<=m;i++)
cin>>b[i].x;
for(int i=1;i<=m;i++)
cin>>b[i].y;
sort(a+1,a+1+n);
sort(b+1,b+1+m,cmp);
int maxx=-inf;
int ans=0;
int pos1=n,pos2=1;
while(b[pos2].y==0) pos2++;
pos2--;
while(pos1&&pos2){
if(a[pos1]>b[pos2].x)
ans+=a[pos1]-b[pos2].x;
else
break;
pos1--,pos2--;
}
maxx=max(ans,maxx);
ans=0;
pos1=n,pos2=m;
int flag=1;
while(b[pos2].y==1){
int pos=lower_bound(a+1,a+1+n,b[pos2].x)-a;
while(vis[pos]&&pos<=n) pos++;
if(pos==n+1){
flag=0;
break;
}
vis[pos]=true;
pos2--;
}
if(flag){
while(pos1&&pos2){
if(vis[pos1]){
pos1--;
continue;
}
if(a[pos1]>b[pos2].x) //这里还是可以贪伤害的
ans+=a[pos1]-b[pos2].x,pos1--,pos2--;
else{
flag=0;
break;
}
}
if(flag){
while(pos1){
if(vis[pos1]){
pos1--;
continue;
}
ans+=a[pos1];
pos1--;
}
}
maxx=max(maxx,ans);
}
cout<<"Case "<<(++cnt)<<": "<<maxx<<endl;
}
}
后话
感谢阅读,希望能对你产生一点用处。
以下台词取自《银魂:完结篇·永远的万事屋》:
(每次看这一段的时候都会疯狂的起鸡皮疙瘩+落泪,真的是太燃了,配合着『現状ディストラクション』的BGM)
(SPYAIR,yyds!)