D. Keiichi Tsuchiya the Drift King:
输入:
4
1 2 2 120
1 2 2 60
1 2 2 30
1 2 2 15
输出:
1.605551275464
1.605551275464
1.598076211353
1.415415569072
题意:
将赛车简化为一个长为 b,宽为 a 的木块。给出弯道半径 r 以及弯道角度 d。若赛车向右转弯漂移时始终保持右前方紧贴弯道,问最窄的赛道宽度为多少能够使得赛车漂移过程中始终处于赛道中。
思路:
根据样例大概可以猜测出当弯道角度大于一定程度的时候同一辆车所需要的最小宽度保持不变,当赛道弯度减小时所需要的赛道宽度也越小(想象一下如果赛道弯度为0度时只需要车宽就足够,当赛道弯度逐渐增大时,漂移过弯车尾离赛道右侧的距离就越大)。而整辆车在漂移的时候距离赛道右边最远的地方就是答案,最远的部分为整辆车的左后方。
上图为两种情况中简单的一种,车身距离弯道中心最远的点与中心的连线(图中蓝线)与弯道末尾与中心的连线(竖直棕线)的夹角设为 ,此时
< d,所求w在图中可以直观看出为勾股定理求出斜边长 - r。
此时左下角与圆心连线与右上角和圆心连线的夹角 大于 d ,这种情况将
- d角设为
,则实际道路宽只需要
这么宽。当 d、b、a如上图(右)所示时,只漂移了一定角度就直行,因此所需要的宽度小于第一种情况。
AC代码:
/*---------------------------------
*File name: D.cpp
*Author: Snpilola
*Creation date: 2019-10-03 18:41
*-------------------------------*/
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define LL long long
#define mkp make_pair
#define PLL pair<LL, LL>
#define lowbit(x) x & (-x)
#define PII pair<int, int>
#define Pque priority_queue
using namespace std;
const int maxn = 1e3 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int EPS = 1e-6;
const double PI = acos(-1.0);
//ICPC 焦作D
int main(){
int T;
scanf("%d", &T);
while(T--){
double a, b, r, d;
scanf("%lf %lf %lf %lf", &a, &b, &r, &d);
d = d / 180 * PI;
double D = atan(b / (a + r));
if(D <= d) printf("%.12lf\n", sqrt((a + r) * (a + r) + b * b) - r);
else{
double E = D - d;
double ans = sqrt(((a + r) * (a + r)) + (b * b)) * cos(E) - r;
printf("%.12f\n", ans);
}
}
return 0;
}
F. Honeycomb:
输入:
1
3 4
+---+ +---+
/ \ / \
+ +---+ +---+
\ \ / \
+ + S +---+ T +
/ \ / /
+ +---+ + +
\ \ / \
+---+ +---+ +
/ /
+ +---+ + +
\ / \
+---+ +---+ +
\ / \ /
+---+ +---+
输出:
7
题意:给出蜂巢的二维地图,给出起点终点,问从起点走到终点的最短路中会走过几个蜂窝。包括起点终点。
思路:简单BFS,只是方向改一改。
坑点:用memset容易T,观察发现只有几个点会被vis标记,只需要将所有可能被标记的点初始化为0就可以。
AC代码:
/*---------------------------------
*File name: F.cpp
*Team: 这题太简单啦
*Author: Snpilola
*Creation date: 2019-10-03 18:41
*-------------------------------*/
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define LL long long
#define mkp make_pair
#define PLL pair<LL, LL>
#define lowbit(x) x & (-x)
#define PII pair<int, int>
#define Pque priority_queue
using namespace std;
const int maxn = 1e3 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int EPS = 1e-6;
int r, c, n, m;
int sx, sy;
int d[6][2] = {{4, 0}, {-4, 0}, {-2, -6}, {-2, 6}, {2, -6}, {2, 6}};
int dd[6][2] = {{2, 0}, {-2, 0}, {-1, -3}, {-1, 3}, {1, -3}, {1, 3}};
int rnd[6][2] = {{0, 4}, {0, -4}, {2, 2}, {2, -2}, {-2, 2}, {-2, -2}};
bool vis[maxn * 4 + 10][maxn * 6 + 10];
char a[maxn * 4 + 10][maxn * 6 + 10];
struct NODE{
int x, y, num;
NODE(int x, int y, int st){
this -> x = x;
this -> y = y;
this -> num = st;
}
};
bool check(int x, int y, int i){
if(x < 0 || x > n || y < 0 || y > m) return 0;
if(vis[x][y] == 1) return 0;
for(int i = 0; i < 6; i++){
if(a[x + rnd[i][0]][y + rnd[i][1]] != '+') return 0;
}
return 1;
}
bool judge(int x, int y){
if(x < 0 || x > n || y < 0 || y > m) return 0;
if(a[x][y] == '\\' || a[x][y] == '/' || a[x][y] == '-') return 0;
if(vis[x][y] == 1) return 0;
return 1;
}
int Bfs(int x, int y){
queue<NODE> q;
NODE ac = NODE(x, y, 1);
q.push(ac);
while(!q.empty()){
ac = q.front(); q.pop();
int nx, ny, dx, dy;
for(int i = 0; i < 6; i++){
nx = ac.x + d[i][0], ny = ac.y + d[i][1];
dx = ac.x + dd[i][0], dy = ac.y + dd[i][1];
if(check(nx, ny, i) && judge(dx, dy)){
if(a[nx][ny] == 'T') return ac.num + 1;
vis[nx][ny] = 1;
q.push(NODE(nx, ny, ac.num + 1));
}
}
}
return -1;
}
int main(){
int t;
scanf("%d", &t);
while(t--){
scanf("%d %d", &r, &c);
getchar();
sx = sy = -1;
n = 4 * r + 3, m = 6 * c + 3;
for(int i = 2; i <= maxn * 4 + 3; i += 4){
for(int j = 4; j <= maxn * 6 + 3; j += 12){
vis[i][j] = 0;
}
}
for(int i = 4; i <= maxn * 4 + 3; i += 4){
for(int j = 10; j <= m * 6 + 3; j += 12){
vis[i][j] = 0;
}
}
for(int i = 0; i < n; i++){
gets(a[i]);
}
//for(int i = 0; i < n; i++) printf("%s\n", a[i]);
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(a[i][j] == 'S'){
sx = i;
sy = j;
break;
}
}
if(sx != -1) break;
}
int ans = Bfs(sx, sy);
printf("%d\n", ans);
}
return 0;
}