【AtCoder】AGC007

AGC007

A - Shik and Stone

若是i + j走過的格子只有一個,那麼就是能夠走到c++

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 +c - '0';
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int H,W,cnt[30];
char s[15][15];
bool vis[15][15];
void Solve() {
    read(H);read(W);
    for(int i = 1 ; i <= H ; ++i) {
        scanf("%s",s[i] + 1);
    }
    for(int i = 1 ; i <= H ; ++i) {
        for(int j = 1 ; j <= W ; ++j) {
            if(s[i][j] == '#') {
                ++cnt[i + j];
                if(cnt[i + j] >= 2) {puts("Impossible");return;}
            }
        }
    }
    puts("Possible");
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

B - Construct Sequences

把a標成\(i*N\)spa

把b標成\((N - i + 1) * N\)code

此時a和b按位相加後相等,而後按照排列的順序,給第一個排列所在的b加0,第二個+1,第三個+2...就能夠了隊列

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 205
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int N;
int a[20005],b[20005],p[20005];
void Solve() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) read(p[i]);
    for(int i = 1 ; i <= N ; ++i) {b[i] = (N - i + 1) * N; a[i] = i * N;}
    for(int i = 1 ; i <= N ; ++i) {
    b[p[i]] += i - 1;
    }
    for(int i = 1 ; i <= N ; ++i) {
    out(a[i]);space;
    }
    enter;
    for(int i = 1 ; i <= N ; ++i) {
    out(b[i]);space;
    }
    enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

C - Pushing Balls

這個須要注意到,當咱們一個球進洞後,其他的球仍是原來的形態,且差距\(d_{i}\)仍然是一個等差數列字符串

咱們每次的指望就是\(\frac{2nd + 2n(2n - 1)x/2}{2n} = d + (2n - 1)x / 2\)get

推一下式子發現新的首項是string

\(d' = (n + 1)d/ n + 5x /2n\)it

\(x' = (n + 2)x / n\)class

而後\(n - 1\),繼續計算gc

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 205
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int N;
db d,x;
void Solve() {
    read(N);
    scanf("%lf%lf",&d,&x);
    db ans = 0;
    while(N) {
    ans += d + (2 * N - 1) / 2.00 * x;
    d = 1.0 * (N + 1) / N * d + 5 * x / (2 * N);
    x = 1.0 * (N + 2) / N * x;
    --N;
    }
    printf("%.10lf\n",ans);
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

D - Shik and Game

至關於除掉我必須從0走到1的點,我在上面須要繞幾個環

很顯然,環是互相分離的,由於若是環的最靠前一個點有錢,走回去的路上錢都會被撿起來

這樣就很容易dp了,咱們能夠把E去掉,求附加的最小時間

\(dp[i]\)表示走到i且i的錢被撿完了的最小附加時間

若是從前面一個\(j\)轉移過來,若\(2(x[i] - x[j]) >= T\),那麼這一圈的附加時間應該是\(2(x[i] - x[j])\),不然應該是T

這兩個分別能夠用前綴最小值和單調隊列維護,複雜度\(O(n)\)

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 205
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int64 dp[100005],pre;
int64 T,E;
int64 x[100005];
int N,p;
deque<int> que;
void Solve() {
    read(N);read(E);read(T);
    for(int i = 1 ; i <= N ; ++i) {read(x[i]);dp[i] = i * T;}
    p = -1;pre = 1e18;
    que.push_back(0);
    for(int i = 1 ; i <= N ; ++i) {
    while(p < i - 1 && 2 * (x[i] - x[p + 2]) > T) {
        ++p;pre = min(pre,dp[p] - 2 * x[p + 1]);
    }
    dp[i] = min(dp[i],pre + 2 * x[i]);
    while(!que.empty() && 2 * (x[i] - x[que.front() + 1]) > T ) {que.pop_front();}
    if(!que.empty()) {
        dp[i] = min(dp[i],dp[que[0]] + T);
    }
    while(!que.empty() && dp[que.back()] > dp[i]) que.pop_back();
    que.push_back(i);
    }
    out(dp[N] + E);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

E - Shik and Travel

咱們記錄一個點對爲這棵子樹中往上延伸的兩條鏈長度\((a,b)\)咱們合併的時候用兩個子樹裏的\((a,b)\)\((c,d)\)合併,二分答案來限制合併的鏈長不超過某個值

合併的時候用含點對少的和含點對多的合併,新合出來的不會超過點對少的的兩倍,少的中每個點對\((a,b)\)能夠找到\((a,u)\),u是另外一棵樹能合出來最小的,b同理

這樣就能夠作了

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int N;
int64 val[MAXN],lim,pre[MAXN];
vector<int> son[MAXN];
vector<pair<int64,int64> > v[MAXN];
vector<pair<int64,int64> > tmp,ano;
bool flag = 0;
void dfs(int u) {
    if(flag) return;
    v[u].clear();
    if(son[u].size() == 0) {v[u].pb(mp(0,0));return;}
    dfs(son[u][0]);dfs(son[u][1]);
    int a = son[u][0],b = son[u][1];
    if(v[a].size() > v[b].size()) swap(a,b);
    tmp.clear();ano.clear();
    for(auto t : v[a]) {
    tmp.pb(mp(t.fi,t.se));tmp.pb(mp(t.se,t.fi));
    }
    sort(tmp.begin(),tmp.end());
    for(auto t : v[b]) {
        ano.pb(mp(t.fi,t.se));ano.pb(mp(t.se,t.fi));
    }
    sort(ano.begin(),ano.end());
    int r = ano.size() - 1;
    pre[0] = ano[0].se;
    for(int i = 1 ; i < ano.size() ; ++i) pre[i] = min(pre[i - 1],ano[i].se);
    for(auto t : tmp) {
    while(r >= 0 && ano[r].fi + val[b] + t.fi + val[a] > lim) --r;
    if(r >= 0) {
        v[u].pb(mp(pre[r] + val[b],t.se + val[a]));
    }
    }
    if(!v[u].size()) flag = 1;
    return;
}
bool check(int64 mid) {
    lim = mid;
    flag = 0;dfs(1);
    if(flag) return false;
    return true;
}
void Solve() {
    read(N);
    int a;
    for(int i = 1 ; i < N ; ++i) {
    read(a);
    son[a].pb(i + 1);read(val[i + 1]);
    }
    int64 L = 0,R = 1e16;
    while(L < R) {
    int64 mid = (L + R) >> 1;
    if(check(mid)) {
        R = mid;
    }
    else L = mid + 1;
    }
    out(L);enter;
}

int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

F - Shik and Copying String

咱們先對每一個點找一個匹配點,這個點就是\(t[i] == s[j]\)且j最小的位置

且對於i的匹配點必須是遞增的

而後咱們至關於從每一個匹配點在一個高度無限,寬度爲字符串長度,開始每步第一次能夠往下走,而後往右走,直到走到匹配的最後一個位置

咱們要求的就是這列路徑的最大高度

從後往前開始遞推,遇到一個結束位置,高度加1,並且全部的降低位置須要+1

若是這一列位置是個降低位置,上面還有c條線,我能夠拖到i - c的位置再降低(咕咕咕是人類的本質)

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 1000005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int N;
char s[MAXN],t[MAXN];
int pos[MAXN],suf[MAXN],to[MAXN],turn[MAXN];
void Solve() {
    read(N);
    scanf("%s",s + 1);
    scanf("%s",t + 1);
    bool f = 1;
    for(int i = 1 ; i <= N ; ++i) {
    if(s[i] != t[i]) {f = 0;break;}
    }
    if(f) {puts("0");return;}
    int p = N;
    for(int i = N ; i >= 1 ; --i) {
    p = min(p,i);
    while(p >= 1 && s[p] != t[i]) --p;
    if(p == 0) {puts("-1");return;}
    if(!pos[p]) pos[p] = i;
    to[i] = p;
    }
    int cnt = 0,t = 0;
    int ans =  0;
    for(int i = N ; i >= 1 ; --i) {
    suf[i] = suf[i + 1];
    if(pos[to[i]] == i) {
        ++suf[i];++cnt;++t;
    }
    ans = max(suf[i],ans);
    if(pos[i]) {
        --cnt;
        turn[i - cnt + t]++;
    }
    suf[i] -= turn[i + t];turn[i + t] = 0;
    }
    out(ans);enter;
}

int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}
相關文章
相關標籤/搜索