2018 ACM-ICPC World Finals - Beijing

2018 ACM-ICPC World Finals - Beijing


A. Catch the Plane

\(dp[v_i,t_i]\)表示时刻\(t_i\)\(v_i\)点,到达终点的最大概率,那么转移方程为:
\(dp[(v_i,t_i)] = max(P_{ij}*dp[(v_{j+1},t_{j+1})] + (1-Pij)*dp[(v_{i+1},t_{i+1})])\)
\(dp[(v_i,t_i)] = max(dp[v_{i+1},t_{i+1}])\)
其中\((v_i,t_i)\)的一个后继状态为\((v_j,t_j)\)两个状态之间的转移概率为\(P_{ij}\),第一种转移:沿\(P_{ij}\)这个方向转移,以及继续留在这个点等待下次转移(\((v_{i+1},t_{i+1})\)为同一位置下与\(t_i\)最接近的下一个时间);第二种转移是:直接选择继续等待的概率。想出这些后,以为可以愉快的ac了。然而调到早上7点。。。才弄好

  • 问题一:%I64d读1e18,蜜汁爆了,换了几个编译器才发现。。。
  • 问题二:为简化代码省略了讨论,导致后面一个点wa
  • 问题三:起点和终点要单独加进去,导致后面一个点wa
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long double LD;
typedef unsigned long long ll;
const int N = 5e6 + 100;
using namespace std;
struct node {
    int x; ll t;
    node(){}node(int a,ll b) {x=a,t=b;}
    bool operator < (const node a) const {
        if(t==a.t) return  x<a.x;
        return t < a.t;
    }
};
bool cmp(node a,node b) {
    if(a.x==b.x) return a.t < b.t;
    return a.x < b.x;
}
bool cmp0(node a,node b) {
    if(a.t==b.t) return a.x > b.x;
    return a.t < b.t;
}
vector<node> v;
map<node,int> id;
node fid[N];
int cnt;

int nxt[N];
LD dp[N];
vector< pair<int,LD> > E[N];
void nwnode(node a) {
    if(id[a]!=0) return;
    ++cnt;
    fid[cnt] = a;
    id[a] = cnt;
}
void add(int a,int b,LD p){
    E[a].pb(make_pair(b,p));
}
int n,m;
ll k;

int main() {int f=0;
    ll MX=0,MN=1000000000000000002LL;
    scanf("%d%d%llu",&m,&n,&k);
    rep(i,1,m) {int a,b;ll s,t; double p;
        scanf("%d %d %llu %llu %lf",&a,&b,&s,&t,&p);
        if(t<=k){
            nwnode(node(a,s));
            nwnode(node(b,t));

            add(id[node(a,s)],id[node(b,t)],(LD)p);
            v.pb(node(a,s));
            v.pb(node(b,t));
            if(b == 1LL) {
                dp[id[node(b,t)]] = 1.0;
                MX = max(t,MX);
            }
            if(a==0){
                if(!f)MN=t;
                else MN=min(MN,t);
                f=1;
            }
        }
    }

    nwnode(node(1,MX));
    nwnode(node(1,k));
    nxt[id[node(1,MX)]] = id[node(1,k)];
    dp[id[node(1,k)]] = 1.0;
    v.pb(node(1,k));
    add(id[node(1,MX)],id[node(1,k)],1.0);

    nwnode(node(0,0));
    v.pb(node(0,0));
    nxt[id[node(0,0)]] = id[node(0,MN)];
    add(id[node(0,0)],id[node(0,MN)],1.0);

    sort(v.begin(),v.end(),cmp);
    for(int i=v.size()-2;i>=0;--i) {
        if(v[i].x==v[i+1].x){
            if(v[i].t == v[i+1].t) nxt[id[v[i]]] = nxt[id[v[i+1]]];
            else nxt[id[v[i]]] = id[v[i+1]];
        }
    }
    sort(v.begin(),v.end(),cmp0);

    for(int i=v.size()-1;i>=0;--i) if(dp[id[v[i]]]==0){
        LD mx = 0;int t = id[v[i]];
        for(int j=0;j<E[t].size();++j) {
            if(fid[nxt[E[t][j].first]].x == fid[E[t][j].first].x && fid[nxt[t]].x == fid[t].x && dp[nxt[t]]!=0 && dp[nxt[E[t][j].first]]!=0 )
                mx = max(mx, E[t][j].second*dp[nxt[E[t][j].first]] + (1.0-E[t][j].second)*dp[nxt[t]]);
            else if(fid[nxt[E[t][j].first]].x == fid[E[t][j].first].x && dp[nxt[E[t][j].first]]!=0)
                mx = max(mx, E[t][j].second*dp[nxt[E[t][j].first]]);
            else if(fid[nxt[t]].x == fid[t].x && dp[nxt[t]]!=0)
                mx = max(mx, (1.0-E[t][j].second)*dp[nxt[t]]);
        }
        if(fid[nxt[t]].x == fid[t].x)
            mx = max(mx, dp[nxt[t]]);
        dp[t] = mx;
    }
    printf("%.10f\n",(double)dp[id[node(0,0)]]);
    return 0;
}

B. Comma Sprinkler

这题没什么难度,把单词取出来直接搜索即可。

#include <bits/stdc++.h>
#define pb push_back
typedef long long ll;
const int N = 1000100;
using namespace std;
string s, word[N];
int cnt;
void chai(string s) {
    int n = s.size();
    cnt = 1;
    for(int i=0;i<n;++i) {
        if(s[i]==' '){
            word[cnt] += ' ';
            ++cnt;
        }
        else
            word[cnt]+=s[i];
    }
}
map< string,vector<string> > pre,last;
string delco(string s) {
    string t;t.clear();
    for(auto c: s) if(c>='a'&&c<='z') t+=c;
    return t;
}
int iscolst(string s) {
    int t = s.size()-1;
    while(t>=0){
        if(s[t]==',')return 1;
        --t;
    }
    return 0;
}
int isbiaolst(string s) {
    int t = s.size()-1;
    while(t>=0){
        if(s[t]=='.'||s[t]==',')return 1;
        --t;
    }
    return 0;
}
map<string,bool> vispre,vislst;
void X(string s);
void Y(string s);
void X(string s) {
    vislst[s] = 1;
    for(int x=0;x<last[s].size();++x) if(!vispre[last[s][x]]) Y(last[s][x]);
}
void Y(string s) {
    vispre[s] = 1;
    for(int x=0;x<pre[s].size();++x) if(!vislst[pre[s][x]]) X(pre[s][x]);
}
string update(string s) {
    s+=',';
    int t=s.size()-1;
    swap(s[t],s[t-1]);
    return s;
}
int main() {
    getline(cin,s); chai(s);
    for(int i=2;i<=cnt;++i) if(!isbiaolst(word[i-1])){
        pre[delco(word[i])].pb(delco(word[i-1]));
    }
    for(int i=1;i<cnt;++i) if(!isbiaolst(word[i])){
        last[delco(word[i])].pb(delco(word[i+1]));
    }
    for(int i=1;i<cnt;++i) {
        string t = delco(word[i]);
        if(!vislst[t]&&iscolst(word[i]))X(t);
    }
    for(int i=2;i<=cnt;++i) {
        string t=delco(word[i]);
        if(!vispre[t]&&iscolst(word[i-1])) Y(t);
    }
    for(int i=1;i<=cnt;++i) {
        string t = delco(word[i]);
        if(vislst[t]&&!isbiaolst(word[i]))
            cout << update(word[i]);
        else
            cout << word[i];
    }puts("");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/RRRR-wys/p/9236861.html