[codeforces 241]C. Mirror Box

试题描述

Mirror Box is a name of a popular game in the Iranian National Amusement Park (INAP). There is a wooden box, 105 cm long and 100cm high in this game. Some parts of the box‘s ceiling and floor are covered by mirrors. There are two negligibly small holes in the opposite sides of the box at heights hl and hr centimeters above the floor. The picture below shows what the box looks like.

In the game, you will be given a laser gun to shoot once. The laser beam must enter from one hole and exit from the other one. Each mirror has a preset number vi, which shows the number of points players gain if their laser beam hits that mirror. Also — to make things even funnier — the beam must not hit any mirror more than once.

Given the information about the box, your task is to find the maximum score a player may gain. Please note that the reflection obeys the law "the angle of incidence equals the angle of reflection".

输入

The first line of the input contains three space-separated integers hl, hr, n (0 < hl, hr < 100, 0 ≤ n ≤ 100) — the heights of the holes and the number of the mirrors.

Next n lines contain the descriptions of the mirrors. The i-th line contains space-separated vi, ci, ai, bi; the integer vi (1 ≤ vi ≤ 1000) is the score for the i-th mirror; the character ci denotes i-th mirror‘s position — the mirror is on the ceiling if ci equals "T" and on the floor if ci equals "F"; integers ai and bi (0 ≤ ai < bi ≤ 105) represent the x-coordinates of the beginning and the end of the mirror.

No two mirrors will share a common point. Consider that the x coordinate increases in the direction from left to right, so the border with the hole at height hl has the x coordinate equal to 0 and the border with the hole at height hr has the x coordinate equal to 105.

输出

The only line of output should contain a single integer — the maximum possible score a player could gain.

输入示例

80 72 9
15 T 8210 15679
10 F 11940 22399
50 T 30600 44789
50 F 32090 36579
5 F 45520 48519
120 F 49250 55229
8 F 59700 80609
35 T 61940 64939
2 T 92540 97769

输出示例

120

数据规模及约定

见“输入

题解

因为光线不能两次触碰到同一面镜子,所以拐点不会超过 n 个,我们不妨枚举拐点个数。确定了拐点个数后,我们设 t 是一个完整斜边(从底边反射上来再触碰到顶)在底边上投影的距离,不难列出一个一元一次方程,把 t 解出来后再遍历一遍每个镜子检查答案是否合法,合法就更新最优得分。枚举拐点个数 O(n),检查合法性 O(n),总时间复杂度 O(n2).

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;

const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
    if(Head == Tail) {
        int l = fread(buffer, 1, BufferSize, stdin);
        Tail = (Head = buffer) + l;
    }
    return *Head++;
}
int read() {
    int x = 0, f = 1; char c = getchar();
    while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); }
    while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); }
    return x * f;
}

#define maxn 110
#define len 100000
const double eps = 1e-6;
int h1, h2, n, cu, cd, ans;
struct Mirror {
	int v, l, r;
	bool operator < (const Mirror& t) const { return l < t.l; }
} up[maxn], down[maxn];

void check(bool cur, double t, double st) {
	bool ok = 0;
	int lu = 1, lastu = 0, ld = 1, lastd = 0, tmp = 0;
	for(; st - len < eps && (lu <= cu || ld <= cd);) {
		if(cur) {
			while(lu < cu && st - up[lu].r > eps) lu++;
			if(st - up[lu].l < eps || st - up[lu].r > eps || lu == lastu) return ;
			tmp += up[lu].v; lastu = lu;
		}
		else {
			while(ld < cd && st - down[ld].r > eps) ld++;
			if(st - down[ld].l < eps || st - down[ld].r > eps || ld == lastd) return ;
			tmp += down[ld].v; lastd = ld;
		}
		st += t; cur ^= 1;
	}
	ans = max(ans, tmp);
	return ;
}

int main() {
	h1 = read(); h2 = read(); n = read();
	for(int i = 1; i <= n; i++) {
		int v = read();
		char tp = getchar();
		while(!isalpha(tp)) tp = getchar();
		if(tp == ‘T‘) up[++cu].v = v, up[cu].l = read(), up[cu].r = read();
		if(tp == ‘F‘) down[++cd].v = v, down[cd].l = read(), down[cd].r = read();
	}

	sort(up + 1, up + cu + 1);
	sort(down + 1, down + cd + 1);
	for(int k = 0; k <= n; k++) {
		// down 0; up 1;
		double t;
		if(k & 1) {
			t = (double)len / ((double)h1 / 100.0 + (100.0 - h2) / 100.0 + k);
			check(0, t, t * h1 / 100.0);
			t = (double)len / ((100.0 - h1) / 100.0 + (double)h2 / 100.0 + k);
			check(1, t, t * (100.0 - h1) / 100.0);
		}
		else {
			t = (double)len / ((double)h1 / 100.0 + (double)h2 / 100.0 + k);
			check(0, t, t * h1 / 100.0);
			t = (double)len / ((100.0 - h1) / 100.0 + (100.0 - h2) / 100.0 + k);
			check(1, t, t * (100.0 - h1) / 100.0);
		}
	}

	printf("%d\n", ans);

	return 0;
}
时间: 2024-11-06 12:13:19

[codeforces 241]C. Mirror Box的相关文章

CodeForces 388A Fox and Box Accumulation (模拟)

A. Fox and Box Accumulation time limit per test:1 second memory limit per test:256 megabytes Fox Ciel has n boxes in her room. They have the same size and weight, but they might have different strength. The i-th box can hold at most xi boxes on its t

CodeForces 388A Fox and Box Accumulation 贪心

Fox Ciel has n boxes in her room. They have the same size and weight, but they might have different strength. The i-th box can hold at most xi boxes on its top (we'll call xi the strength of the box). Since all the boxes have the same size, Ciel cann

[codeforces 241]A. Old Peykan

试题描述 There are n cities in the country where the Old Peykan lives. These cities are located on a straight line, we'll denote them from left to right as c1, c2, ..., cn. The Old Peykan wants to travel from city c1 to cn using roads. There are (n - 1) 

CF578F Mirror Box 【图论,Matrix-Tree】

题目链接:LUOGU 题目描述:在一个 \(n\times m\) 的网格图中,每个格子里摆放着一个镜子,两种情况 /和\. 一个网格合法,当且仅当从任意一个边界段垂直射进网格中,光线会从相邻的边界段射出,同时网格中的每一段都被至少一条光线穿透. 现在网格中有 \(k\) 个位置的镜子形状不确定(用*表示),求合法网格数量\(\text{mod} \ p\). 数据范围:\(n,m\le 100,k\le 200,3\le p\le 10^9+7\),\(p\) 为质数. 题解分析:首先你要知道

用js实现图片自动加载的瀑布流效果

向下滑动网页的时候能够自动加载图片并显示. 盛放图片的盒子模型如下: <div class="box"> <div class="box_img"> <img src="Img/8.jpg"> </div> </div> 设置img-width为150px,然后box_img添加内边距和阴影效果,box的外边距为0,添加内边距.盒子的宽度是由img-width和边距撑开的.也就是说盒子之

html跳动的心实现代码

<style> .box{ width: 200px; height: 400px; position: relative; margin: 30px auto; transform: all 0.5s; } @keyframes moves{ from{box-shadow: 0 0 0 transparent;} 30%{box-shadow: 0 0 50px rgb(236, 57, 57);} 60%{box-shadow: 0 0 80px rgb(241, 97, 97);} }

Codeforces 436E Cardboard Box (看题解)

Cardboard Box 贪了个半天贪不对, 我发现我根本就不会贪心. 我们先按b排序, 然后枚举选两颗心的b的最大值, 在这个之前的肯定都要选一个, 因为前面的要是一个都没选的话, 你可以把当前选两颗心的替换成前面选两颗心, 然后用平衡树或者线段树维护一下前k大和就好啦. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define P

Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) B. Box 贪心

B. Box Permutation p is a sequence of integers p=[p1,p2,-,pn], consisting of n distinct (unique) positive integers between 1 and n, inclusive. For example, the following sequences are permutations: [3,4,1,2], [1], [1,2]. The following sequences are n

Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) B Box

#include<bits/stdc++.h> using namespace std; int shu[100005]; int ans[100005]; int main() { int total; cin>>total; while(total--) { int n; bool flag=true; cin>>n; unordered_set<int>tree; set<int>num; for(int i=1; i<=n; i++