[CQOI2010] 鼹鼠
考场碰到直接 jj
题目背景是 分形图 + 三角函数 。
一个基本想法就是把空的位置建出来,然后跑搜索,对每个格子求面积。
那么我们知道一个格子的倾斜角度和水的深度,就可以计算出上下左右格子中水的深度。
-
( x , y + 1 ) (x,y+1) (x,y+1): h → max ( 0 , h − sin θ ) h\to \max(0,h-\sin \theta) h→max(0,h−sinθ)
-
( x , y − 1 ) (x,y-1) (x,y−1): h → min ( sin θ + cos θ , h + sin θ ) h\to \min(\sin \theta+\cos \theta,h+\sin \theta) h→min(sinθ+cosθ,h+sinθ)
- ( x − 1 , y ) (x-1,y) (x−1,y) : h → max ( 0 , h − cos θ ) h\to \max(0,h-\cos \theta) h→max(0,h−cosθ)
4.
(
x
+
1
,
y
)
(x+1,y)
(x+1,y) :
h
→
min
(
sin
θ
+
cos
θ
,
h
+
cos
θ
)
h\to \min(\sin \theta+\cos\theta,h+\cos\theta)
h→min(sinθ+cosθ,h+cosθ)
总结:影响淹没面积的因素主要是 容器的形状 和 倾斜角度 。对于不同的容器,要具体分析,定性(升高还是降低啊,会不会被容器的形状阻隔啊) + 定量分析(抽取一个方格进行研究,确定水位上升的具体值)。
最后根据每个方格中水的深度算淹没面积。当 >45 时, sin 和 cos 要颠倒一下。
注意精度问题 qwq 。
#include<bits/stdc++.h>
#define db double
using namespace std;
const int N=1<<12;
int n,du,vis[N][N],to[N][N],f[15];
db res;
db pi=atan(1)*4,sx,cx;
db calc(db h) {
if(du<=45) {
if(h<=sx) return h*h;
if(h<=cx) return (2*h-sx)*sx;
h=sx+cx-h;
return 2*sx*cx-h*h;
}
else {
if(h<=cx) return h*h;
if(h<=sx) return (2*h-cx)*cx;
h=sx+cx-h;
return 2*sx*cx-h*h;
}
}
void dfs(int x,int y,db h) {
if(h<=0) return;
h=min(h,sx+cx);
to[x][y]=1,res+=(du==0)?1:calc(h);
if(x>1&&!to[x-1][y]&&vis[x-1][y]) dfs(x-1,y,h+cx);
if(x<f[n]-1&&!to[x+1][y]&&vis[x+1][y]) dfs(x+1,y,h-cx);
if(y>1&&!to[x][y-1]&&vis[x][y-1]) dfs(x,y-1,h+sx);
if(y<f[n]-1&&!to[x][y+1]&&vis[x][y+1]) dfs(x,y+1,h-sx);
}
int main() {
for(int i=0;i<=12;i++) f[i]=1<<i;
scanf("%d%d",&n,&du);
sx=sin(pi/180*du),cx=cos(pi/180*du);
vis[1][1]=1;
for(int siz=2;siz<=n;siz++) {
for(int i=f[siz]-1;i>=f[siz-1]+1;i--) {
for(int j=1;j<=f[siz-1]-1;j++) {
vis[i][j]=!vis[f[siz-1]-j][i-f[siz-1]];
}
for(int j=f[siz-1]+1;j<=f[siz]-1;j++) {
vis[i][j]=!vis[j-f[siz-1]][i-f[siz-1]];
}
}
for(int i=1;i<=f[siz-1]-1;i++) {
for(int j=f[siz-1]+1;j<=f[siz]-1;j++) {
vis[i][j]=vis[i][j-f[siz-1]];
}
}
for(int i=1;i<=f[siz]-1;i++) {
vis[f[siz-1]][i]=1;
}
for(int i=f[siz]-1;i>=f[siz-1];i--) {
vis[i][f[siz-1]]=1;
}
}
for(int i=1;i<=f[n]-1;i++) {
//容器开口的深度为 cos \theta
if(vis[f[n]-1][i]) dfs(f[n]-1,i,cx);
}
if(du!=0) res/=2*sx*cx;
printf("%.6lf",res);
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体