A. Xu Xiake in Henan Province(签到)
题目链接:codeforces2018 焦作 A
题意:
输入4个数,代表去过 4 个地方,如果 4 个数都是 0,输出 Typically Otaku,如果有 3 个 0,输出 Eye-opener,如果有 2 个 0,输出 Young Traveller,如果有 1 个 0,输出 Excellent Traveller,如果没有 0,输出 Contemporary Xu Xiake
解题思路:
....无
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+5;
const double pi = acos(-1);
int a[maxn];
int main(){
int t;
cin >> t;
while(t--){
int a, ans = 0;
for(int i = 1; i <= 4; i++){
cin >> a;
if(a != 0){
ans++;
}
}
if(ans == 0){
cout << "Typically Otaku" << endl;
}
if(ans == 1){
cout << "Eye-opener" << endl;
}
if(ans == 2){
cout << "Young Traveller" << endl;
}
if(ans == 3){
cout << "Excellent Traveller" << endl;
}
if(ans == 4){
cout << "Contemporary Xu Xiake" << endl;
}
}
return 0;
}
D. Keiichi Tsuchiya the Drift King(几何)
题目链接:codeforces 2018焦作 D
题意:
弯道漂移,在车(车子抽象为矩形)不碰到两边马路的情况下,马路的最小宽度。
解题思路:
其实只有两种状态
1. 弯道很短,所以车子在前车身出了弯道的情况下,后车身还没进弯道,如图所示

已知a,b,r,角SOT,现在求 W
在三角形 UOK 中 ∠UOK = atan( UK / UO) [ UK = b, UO = a+r ]
那么∠TOK = ∠UOK- ∠SOT
OK = b / sin(∠UOK)
OT = r + W = OK * cos(∠TOK)
将变量带入得
W = b / sin(∠UOK) * cos(∠TOK) - r = b / sin(atan(b / (a + r))) * cos(atan(b / (a + r)) - d)
2.弯道足够长,以至于在漂移过程中车身全部可以在圆弧内,如下图所示

W = OT - r
∠UOT = atan(TU / UO)
OT = TU / sin(∠UOT)
W = b / sin(∠UOT) - r = b / sin(atan(TU / UO)) - r ;
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const double pi = acos(-1);
int main(){
int t;
cin >> t;
while(t--){
double a, b, r, d;
cin >> a >> b >> r >> d;
double o = atan(b/(a+r));
double ans = b / sin(o);
if(o > d/180.0 * pi){
o = o - d / 180.0 * pi;
ans = ans * cos(o) - r;
}
else{
ans = ans - r;
}
printf("%.15lf\n", ans);
}
return 0;
}
E. Resistors in Parallel(规律)【我这种菜鸡找不出来】
题目链接:codeforces 2018焦作 E
题意:
选一个小于等于n(10^100)的无平方因子的数,它的电阻阻值就是它的所有因子的倒数和的倒数,求这个最小的阻值。
解题思路:
打表找规律,
分子后一个等于前一个乘以2,3,5,7,11..
分母1 3 12 72 576.... 等于前一个乘2+1, 3+1,5+1 ,7+1
n太大,所以用java大数写
import java.util.*;
import java.math.*;
public class Main {
static Scanner cin = new Scanner (System.in);
static boolean [] vis = new boolean [521];
static BigInteger [] dp = new BigInteger[521];
static int [] pr = new int [521];
static int cnt=0;
static void getpr() {//欧拉筛 找素数
vis[0]=vis[1]=true;
for (int i = 2; i <= 520;i++) {//只要使所有的素数乘起来大于10^100就好
if(!vis[i]) pr[++cnt]=i;
for (int j = 1; j <= cnt && i*pr[j] <= 520;j++) {
vis[i*pr[j]]=true;
if(i%pr[j]==0) break;
}
}
}
public static void main(String[] args) {
getpr();
int t=cin.nextInt();
while(t-->0) {
int k;
BigInteger sum = cin.nextBigInteger();
BigInteger ans = BigInteger.ONE;
dp[0]=BigInteger.ONE;
for (k = 1;ans.multiply(BigInteger.valueOf(pr[k])).compareTo(sum)<=0;k++) {
ans=ans.multiply(BigInteger.valueOf(pr[k]));
}
k--;
for (int i = 1; i <= k;i++) {
dp[i]=dp[i-1].add(dp[i-1].multiply(BigInteger.valueOf(pr[i])));
}
BigInteger gcd=ans.gcd(dp[k]);
System.out.println(ans.divide(gcd)+"/"+dp[k].divide(gcd));//直接除以最大公因数
}
}
}
F. Honeycomb(加强BFS)
题目链接:codeforces 2018焦作 F
题意:
给定n ,m表示一共 n 行,每行m个蜂巢,求从S到T的最短路径
解题思路:
思路来自大佬 : 大佬博客
从蜂巢正中心出发,然后向6个方向走,判断是否有墙,将每个蜂巢的中心点当做固定点,即要到达这个蜂巢就将坐标定位在这个蜂巢的中心点
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int N = 1e4+5;
char G[N][N];
int n, m, sx, sy;
int mov[6][2]={ {-2,0},{2,0},{-1,-3},{-1,3},{1,-3},{1,3} };
struct node{
int x, y, step;
};
int bfs() {
queue<node> q;
q.push((node){sx, sy, 1});
while(!q.empty()) {
node e = q.front();
q.pop();
for(int i = 0; i < 6; i++) {
int x1 = e.x + mov[i][0];
int y1 = e.y + mov[i][1];
int x2 = x1 + mov[i][0];
int y2 = y1 + mov[i][1];
if(G[x1][y1] == ' ' && G[x2][y2] == 'T'){
return e.step+1;
}
if(G[x1][y1] != ' ' || G[x2][y2] != ' '){
continue;
}
G[x2][y2] = '$';
q.push((node){x2, y2, e.step+1});
}
}
return INF;
}
int main(){
int t;
scanf("%d", &t);
while(t--){
scanf("%d%d", &n, &m);
getchar();
n = n * 4 + 3;
m = m * 6 + 3;
for(int i = 1; i <= n; i++) {
char ch;
G[i][0] = ' ';
int j = 1;
while(~scanf("%c", &ch) && ch != '\n') {
G[i][j] = ch;
if(ch == 'S'){
sx = i;
sy = j;
}
j++;
}
G[i][j] = '\0';
}
int ans = bfs();
if(ans == INF) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
I. Distance(思维)
题目链接:codeforces 2018焦作 I
题意:
给你n个点相邻点之间的距离
让你选(1~n)个点,使它们之间的距离和最大
输出选(1~n)个点的情况
解题思路:
分析得出,分别从两边往中间选是最优的,那样中间的距离可以被利用多次(注意开long long ) 否则wrong anser 2
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
ll a[maxn];
int main(){
int t;
cin >> t;
while(t--){
ll n, sum = 0;
cin >> n;
for(int i = 1; i < n; i++){
cin >> a[i];
sum = sum + a[i];
}
ll m = sum, ans = sum, l = 1;
cout << 0 << " " << sum;
for(int i = 1; i < n -1; i++){
if(i % 2 == 0){
sum = sum - a[l] - a[n-l];
m = m + sum;
l++;
}
ans = ans + m;
cout << " " << ans;
}
cout << endl;
}
return 0;
}
本文解析了Codeforces2018焦作赛题A至F及I题,涵盖旅行者问题、几何漂移、并联电阻、蜂巢路径及点间距离最大化等,详细介绍了各题的题意、解题思路及代码实现。
D(几何)E(规律)F(加强版bfs)I(思维)&spm=1001.2101.3001.5002&articleId=102052745&d=1&t=3&u=5ac105f7ba864ecd883d9df26d593904)
412

被折叠的 条评论
为什么被折叠?



