社区讨论

90ptsWA on pts9

P11232[CSP-S 2024] 超速检测参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mhj3uvib
此快照首次捕获于
2025/11/03 20:17
4 个月前
此快照最后确认于
2025/11/03 20:17
4 个月前
查看原帖
CPP
#include <iostream>
#include <algorithm>
#include <map>
#define int long long
using namespace std;
int t;

int a[2000000], d[2000000], v[2000000], p[2000000], sum[2000000];
pair<double, double> dp[2000000];

void solve(){
	int n, m, l, V;
	cin >> n >> m >> l >> V;
	memset(dp, 0, sizeof(dp));
	memset(sum, 0, sizeof(sum));
	for(int i = 1; i <= n; i++){
		cin >> d[i] >> v[i] >> a[i];
	}
	for(int i = 1; i <= m; i++){
		cin >> p[i];
		sum[p[i]]++;
	}
	sort(p +1, p + m + 1);
	for(int i = 2; i <= l; i++){
		sum[i] += sum[i - 1];
	}
	for(int i = 1; i <= n; i++){
		int di = d[i];
		int vi = v[i];
		int ai = a[i];
		if(ai == 0){
			if(vi > V){
				dp[i].first = di;
				dp[i].second = l;
			} else {
				dp[i].first = -1;
				dp[i].second = -1;
			}
		} else if(ai < 0){
			if(vi <= V){
				dp[i].first = -1;
				dp[i].second = -1;
			} else {
				double dx = ((double)(V * V - vi * vi) / (2 * ai));
				dp[i].first = di;
				dp[i].second = dx + di;
				if(dp[i].second >= l){
					dp[i].second = l;
				}
				if((V * V - vi * vi) % (2 * ai) == 0){
					dp[i].second -= 1;
				} else {
					dp[i].second = floor(dp[i].second); 
				} 
			}
		} else if(ai > 0){
			if(vi > V){
				dp[i].first = di;
				dp[i].second = l;
			} else if(vi == V){
				dp[i].first = 1 + di;
				dp[i].second = l;
			} else {
				double dx = ((double)(V * V - vi * vi) / (2 * ai));
				dp[i].first = dx + di;
				dp[i].second = l;
				if((V * V - vi * vi) % (2 * ai) == 0){
					dp[i].first += 1;
				}
				if(dp[i].first >= l){
					dp[i].first = -1;
					dp[i].second = -1;
				} else if((V * V - vi * vi) % (2 * ai) != 0){
					dp[i].first = ceil(dp[i].first);
				}
			}
		}
	}
	int res = 0;
	for(int i = 1; i <= n; i++){
        if(dp[i].first != -1){
            int l = lower_bound(p + 1, p + m + 1, dp[i].first) - p;
            int r = upper_bound(p + 1, p + m + 1, dp[i].second) - p - 1;
            if(l != m + 1){
                l = p[l];
                r = p[r];
                dp[i].first = r;
                dp[i].second = l;
                int ans = 0;
                if(sum[r] - sum[l - 1]){
                    res += 1;
                }
            } else {
                dp[i].first = -1;
                dp[i].second = -1;
            }
        }
	}
    sort(dp + 1, dp + n + 1);
    int rightest = -1, sum = 0;
    for(int i = 1; i <= n; i++){
        if(dp[i].first != -1){
            if(dp[i].first >= dp[i].second){
                if(dp[i].second > rightest){
                    rightest = dp[i].first;
                    sum += 1;
                } 
            }
        }
    }
    cout << res << " " << m - sum << endl;
}
 
signed main(){
	// freopen("detect5.in", "r", stdin);
	cin >> t;
	while(t--){
		solve();
	}
}

大概思路

先统计出每辆车一定超速的初始位置和结束位置,再利用二分统计出每个离初始位置和结束位置最近且在区间内的两个检测器未知,最后考虑按右边界排序贪心。

问题

pts9的第17个子测试点 正确输出为 2970 991 该程序输出为 2970 990

回复

1 条回复,欢迎继续交流。

正在加载回复...