1. 程式人生 > >Final Round (Codeforces Round #414, rated, Div. 1 + Div. 2) 題解

Final Round (Codeforces Round #414, rated, Div. 1 + Div. 2) 題解

A:

有一個強盜企圖搶劫一個銀行,然後他失敗了(wtf...?)
這導致這個銀行的顧客Oleg想要搞點事情。。?
現在有很多個保險箱排成一列每個保險箱要麼是空的要麼有一些支票
現在Oleg在第b個保險箱的位置
同時在位置a,a<b以及位置c,b<c各有一名保安
這兩個保安很懶。。所以他們並不想動
Oleg每次可以選擇向左或者向右移動一格
請問他最多能拿到多少支票???
1a<b<c109
共有n1n105張支票,第i張支票位於保險箱xi

Solution A:

顯然夾在a,c之間的支票都是拿得到的
於是掃描一遍就行了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
#include<ext/pb_ds/priority_queue.hpp>
using
namespace std; int main() { #ifdef DMC freopen("DMC.txt","r",stdin); #endif int a,b,c,n,x,Ans = 0; cin >> a >> b >> c >> n; while (n--) { scanf("%d",&x); Ans += (b < x && x < c) ? 1 : 0; } cout << Ans << endl; return
0; }

B:

Igor養了n只兔子
大家都知道兔子喜歡吃胡蘿蔔
於是Igor買了個一根胡蘿蔔
這根胡蘿蔔可以看做一個底邊長為1高為h的等腰三角形
Igor想通過切n1刀把這根胡蘿蔔分成面積相等的n
並且每刀都平行於底邊
請輸出每刀離等腰三角形頂部的距離
2n10001h105

Solution B:

將這個等腰三角形的頂點作為原點
中垂線方向作為x軸正方向,建立平面直角座標系
首先每隻兔子能分到的胡蘿蔔面積為定值S=h2n
處於x軸正上方的那條直線解析式顯然為f(x)=12hx
每隻兔子分到的胡蘿蔔都可以看做一個梯形
設當前這一刀切在距離頂點a的地方
設下一刀離當前距離為x
那麼就是解方程[f(a)+f(a+x)]x=S
展開發現是個一元二次方程
用判別式暴力解過去就行了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;

typedef double DB;

int main()
{
    #ifdef DMC
        freopen("DMC.txt","r",stdin);
    #endif

    int n,h; cin >> n >> h;
    DB A = 0,tmp = 4.00 * (DB)(h) * (DB)(h) / (DB)(n);
    for (int i = 1; i < n; i++)
    {
        DB x = (-2.00 * A + sqrt(4.00 * A * A + tmp)) / 2.00;
        A += x; printf("%.12lf ",A);
    }
    return 0;
}

C:

OlegIgor打算開個公司
首先得給他們的公司取個名字
OlegIgor各有一個大小為n的可重字元集合
他們打算通過一個遊戲確定一個長度為n的公司名稱
一開始,公司的名字可以看做一個長度為n全是的字串
每一次,Oleg或者Igor可以選擇自己集合的一個字元填充任意一個
遊戲從Oleg先手,兩人輪流操作
Oleg的目的是讓公司名稱的字典序儘可能小
Igor的目的是讓公司名稱的字典序儘可能大
請問最後確定的公司名稱會是什麼?
1n3105

Solution C:

對於Oleg,將他的字符集按照升序排好,顯然他只會用前n2
對於Igor,將他的字符集按照降序排好,顯然他只會用前n2
有一個直觀的貪心
每次輪到Oleg,把剩餘字元中最小的填在第一位
每次輪到Igor,把剩餘字元中最大的填在第一位
不過顯然有特殊情況
如果Igor剩餘的所有字元都不大於Oleg剩下的
那麼Oleg拿剩餘最小的填在第一位顯然不優
那麼就拿一個最大的填在最後面,把前面的留給對手
對於Igor也是一樣的策略
因此加個特判就行了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;

const int maxn = 3E5 + 3;

int n;
char A[maxn],B[maxn],C[maxn];

int main()
{
    #ifdef DMC
        freopen("DMC.txt","r",stdin);
    #endif

    scanf("%s",A + 1); scanf("%s",B + 1); n = strlen(A + 1);
    sort(A + 1,A + n + 1); sort(B + 1,B + n + 1); reverse(B + 1,B + n + 1);
    int L = 1,R = n,la = 1,ra = n + 1 >> 1,lb = 1,rb = n >> 1;
    for (int i = 1; i <= n; i++)
    {
        if (i & 1)
        {
            if (A[la] >= B[lb]) C[R--] = A[ra--];
            else C[L++] = A[la++];
        }
        else
        {
            if (B[lb] <= A[la]) C[R--] = B[rb--];
            else C[L++] = B[lb++];
        }
    }
    for (int i = 1; i <= n; i++) putchar(C[i]);
    return 0;
}

D:

Oleg有一張n個點m條邊的無向連通圖
現在他想給圖中每個點一個標號
記第i個點的標號為xi
對於圖中任意一個點對(u,v)(uv