首页 > 其他分享 >2019-2020 ICPC Northwestern European Regional Programming Contest (NWERC 2019):GH

2019-2020 ICPC Northwestern European Regional Programming Contest (NWERC 2019):GH

时间:2024-09-02 11:36:14浏览次数:13  
标签:Northwestern ld Contest int 横坐标 2019 ans include id

前言

目前打过的最逆天的一场,前半场CF评测机度假去了,全场In queue,两小时左右评测机终于回来了,Standings遍地开花,听取WA声一片。
昨天就有好几道题是因为没及时看题所以没做,赛后还和队友商量说应该先把所有题大致看一遍,结果今天不长记性,还没看H和J,就去写思路不一定对+实现起来难得要死的D,最后还没做出来。要是把这时间拿去做H,多半能搞出来。明天一定长记性。一定。


G. Gnoll Hypothesis

题意

不细说了,大家应该都做了而且都会做,但好像都用组合数算的,我来点不太一样的思路。

解法

n个怪物有k个要被选中,现在考虑x号怪物,在所有方案中它被选中的概率其实就是k/n,它的答案就加上s[x] * k/n。接下来还剩n-1个怪物,要选k-1个,也就是要有(n-1)-(k-1) = (n-k)个不被选中,那x的前一个怪物不被选中的概率其实就是(n-k)/(n-1),答案就加上s[x-1] * k/n * (n-k)/(n-1)。依此类推。也就是说初始概率p为n/k,往前推到x-i个位置,p就乘上(n-k-i+1)/(n-i),然后x位置的答案加上s[x-i] * p即可。
虽然本质和组合数的方法一样,但想起来好像要容易很多……反正对本数学蒟蒻来说是这样的。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ld long double
using namespace std;
const int N = 1005;

int n, k, fz, fm;
ld a[N], p, ans[N];

int main(){
    cin >> n >> k;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        a[i + n] = a[i];
    }
    for(int i = n + 1; i <= n * 2; i++){
        p = (ld)k / (ld)n;
        fz = n - k;
        fm = n - 1;
        ans[i - n] = p * a[i];
        for(int j = 1; j <= n - k; j++){
            p = p * (ld)fz / (ld)fm;
            ans[i - n] += p * a[i - j];
            fz--;
            fm--;
        }
    }
    for(int i = 1; i <= n; i++){
        if(i > 1) printf(" ");
        printf("%.12Lf", ans[i]);
    }
    return 0;
}

H. Height Profile

题意

平面上有n+1个点,它们的横坐标依次是从0到n的整数,从左到右依次给出每个点的纵坐标,然后把这些点从左到右顺次相连,形成一条折线。k次询问,每次给出一个斜率g(下面的代码里写成q了),问这条折线上是否存在两个点,它们的连线的斜率不小于g。如果有,求出这两个点的横坐标的最大差值;如果没有,输出-1。

解法

边画边想,容易想到 如果存在这样的两个点,那么它们至少有一个横坐标是整数[1]。首先考虑暴力解法:枚举每个横坐标为整数的点,分别找到 它左侧横坐标最小的、它右侧横坐标最大的 两个可行的横坐标为整数的点,如果这两个点不是第0个、第n个点,可以简单地用数学方法求得向左、向右最多能延伸到什么位置。然后更新答案即可。

[1] 假设两个端点横坐标都不是整数,也就是说它们都位于折线的某一段的中间。如果这两段的斜率相等,那找到的线段就可以 两个端点固定在折线上 任意平移。那我们把线段平移到可行的最左端或最右端位置,这种情况就相当于两个点横坐标都是整数。如果两段斜率不相等,那我们可以向上或向下移动这条线段,使得它长度变长且斜率不变,就不是最优解了。

可是上述做法时间复杂度能达到O(k·n2),会TLE。设上述过程中枚举到某个横坐标为r的点时,找到的左侧最远的可行点是l,就有(h[r]-h[l])/(r-l) ≥ g,也就是h[r]-rg ≥ h[l]-lg。可以把所有整数横坐标的点按h[i]-ig从小到大排序。从前往后遍历,枚举到横坐标为i的点时,已经遍历过的点中横坐标最小的点,就是左侧要找的点。直接更新答案即可。找右侧可行点同理。时间复杂度只有O(k·nlogn),可以通过。

唉,读完题思路就差不多了,可惜只剩半小时的时候才看这题,难受qwq

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#define ll long long
#define ld long double
using namespace std;
const int N = 1e5 + 5;
const ll INF = 1e18;

int n, k;
ld h[N], q;
struct node{
    int id;
    ld mk;
    node(int id1 = 0, ld mk1 = 0){
        id = id1;
        mk = mk1;
    }
    bool operator < (const node &n1) const{
        if(mk == n1.mk) return id < n1.id;
        return mk < n1.mk;
    }
}d[N];

int main(){
    cin.tie(0);
    cin >> n >> k;
    for(int i = 0; i <= n; i++){
        cin >> h[i];
    }
    while(k--){
        cin >> q;
        q *= 10;
        ld ans = 0;
        for(int i = 0; i <= n; i++){
            d[i] = node(i, h[i] - (ld)i * q);
        }
        sort(d, d + 1 + n);
        int minpos = d[0].id;
        for(int i = 1; i <= n; i++){
            if(d[i].id < minpos){
                minpos = d[i].id;
                continue;
            }
            ld cur = (ld)(d[i].id - minpos);
            if(minpos > 0){
                cur += (h[d[i].id] - q * cur - h[minpos]) / (q - h[minpos] + h[minpos - 1]);
            }
            ans = max(ans, cur);
        }
        int maxpos = d[n].id;
        for(int i = n - 1; i >= 0; i--){
            if(d[i].id > maxpos){
                maxpos = d[i].id;
                continue;
            }
            ld cur = (ld)(maxpos - d[i].id);
            if(maxpos < n){
                cur += (h[maxpos] - q * cur - h[d[i].id]) / (q - h[maxpos + 1] + h[maxpos]);
            }
            ans = max(ans, cur);
        }

        if(ans == 0){
            printf("-1\n");
        }
        else{
            printf("%.12Lf\n", ans);
        }
    }
    return 0;
}

标签:Northwestern,ld,Contest,int,横坐标,2019,ans,include,id
From: https://www.cnblogs.com/qjsswz/p/18392419

相关文章

  • SDKD 2024 Summer Training Contest F2(The 13th Shandong ICPC Provincial Collegiat
    A-Orders题意每天能生产k个产品的工厂有n个订单,第i个订单是在a_i天交b_i个产品,问能否交付。思路订单按日期排序,记录剩下的商品.代码#define_CRT_SECURE_NO_WARNINGS#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintmxn=1e6+5......
  • 招商银行信用卡中心2019秋招IT笔试——比特币最佳买卖时机
    给定一个正整数数组,它的第 i 个元素是比特币第 i 天的价格。如果你最多只允许完成一笔交易(即买入和卖出一次),设计一个算法来计算你所能获取的最大利润。注意你不能在买入比特币前卖出。时间限制:C/C++1秒,其他语言2秒空间限制:C/C++32M,其他语言64M输入描述:正整数数组,为......
  • AtCoder Beginner Contest 369 补题记录
    A-369题意:给定A和B,求有多少个x可以和A,B构成等差数列思路:分三种情况讨论A==B则x不得不与A和B想等x位于A和B中间只有B-A为偶数才有这种情况存在x位于A和B两边可以在左边也可以在右边,只要A!=B这种情况总会存在voidsolve(){inta=read(),b=read();......
  • AtCoder Beginner Contest 368(ABC368)
    [ABC369C]CountArithmeticSubarrays题意:判断有多少个区间是等差数列(不能重排)。\(1\len\times10^5\)。思路:赛时看错题了,以为这个区间可以重排,卡了8min,小丑了。首先容易注意到,对于一个区间\([l,r]\),若其是等差数列,则这个区间的子区间\([l',r']\)肯定也是子序列,造成......
  • Windows Server 2019 OVF, updated Aug 2024 (sysin) - VMware 虚拟机模板
    WindowsServer2019OVF,updatedAug2024(sysin)-VMware虚拟机模板2024年8月版本更新,现在自动运行sysprep,支持ESXiHostClient部署请访问原文链接:https://sysin.org/blog/windows-server-2019-ovf/,查看最新版。原创作品,转载请保留出处。现在都是自动sysprep的......
  • Atcoder Beginner Contest 369
    AtcoderBeginnerContest369C-CountArithmeticSubarrays题意给出一个长度为\(n\)的序列\(A\),求有多少个\(A\)的连续子序列为等差数列。思路对于递增的右端点,左端点不减。使用双指针,枚举右端点,扫描左端点。时间复杂度:\(O(n)\)。代码#include<bits/stdc++.h>usi......
  • AtCoder Beginner Contest 369 补题记录(A~G)
    AconstintN=1000100;inta[N];signedmain(){intx,y;cin>>x>>y;if(x==y)cout<<"1\n";elseif(x%2==y%2)cout<<"3\n";elsecout<<"2\n";}BconstintN=1000100;inta[N];sign......
  • AtCoder Beginner Contest 369 A~D
    封面原图画师かにょこAtCoderBeginnerContest369我愿称之为等差数列场A-369题意给两个数,问能和他们构成等差数列的数有多少个代码#include<bits/stdc++.h>#definemod998244353usingnamespacestd;typedeflonglongll;typedefdoubledb;type......
  • Atcoder Beginner Contest 369
    AtcoderBeginnerContest369唯一的一发罚时吃在A题,消息了。A挂一发的原因是以为\(A,B\)都是一位数,然后循环范围开了\([-10,20]\)。#include<bits/stdc++.h>usingnamespacestd;intmain(){ ios::sync_with_stdio(false),cin.tie(nullptr);// int_;cin>>_;while......
  • AtCoder Beginner Contest 053
    A-ABC/ARC#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;intmain(){ ios::sync_with_stdio(false),cin.tie(nullptr); intx; cin>>x; if(x<1200)cout<<"ABC"; elsecout<<"ARC&q......