题解 2017-2018 ACM-ICPC East Central North America Regional Contest (ECNA 2017)

A - Abstract Art

问n个多边形的面积并是多少。
直接粘板子过了…

#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const double pi = acos(-1.0);

typedef long long LL;
typedef unsigned long long ULL;
void umax(int &a, int b) {
    a = max(a, b);
}
void umin(int &a, int b) {
    a = min(a, b);
}

void file() {
    freopen("input1.txt", "r", stdin);
//    freopen("1.txt", "w", stdout);
}
/*

*/

namespace Solver {
    #define PDI pair<double,int>
    #define point pair<double,double>
    #define mp make_pair
    #define pb push_back
    #define x first
    #define y second
    #define zero 1e-8
    #define maxN 111
    #define maxp 30
    point operator +(point a,point b) {
        return mp(a.x+b.x,a.y+b.y);
    }
    point operator -(point a,point b) {
        return mp(a.x-b.x,a.y-b.y);
    }
    double operator *(point a,point b) {
        return a.x*b.y-b.x*a.y;
    }
    double operator ^(point a,point b) {
        return a.x*b.x+a.y*b.y;
    }
    inline double cross(point o,point a,point b) {
        return (a-o)*(b-o);
    }
    inline int cmp(double x) {
        if (fabs(x)<zero) return 0;
        return x>0? 1:-1;
    }
    class Polygon {
    private:
        int i;
        double s;
    public:
        int n;
        point p[maxp];
        point& operator[] (int idx) {
            return p[idx];
        }
        void input() {
            for (i=0; i<n; i++) scanf("%lf %lf",&p[i].x,&p[i].y);
            p[n]=p[0];
        }
        double Area() {
            for (s=0,i=0; i<n; i++) s+=p[i]*p[i+1];
            return s/2;
        }
    };
    PDI s[maxN*maxp*2];
    Polygon P[maxN];
    double S,ts;
    int N;
    inline double seg(point o,point a,point b) {
        if (cmp(b.x-a.x)==0) return (o.y-a.y)/(b.y-a.y);
        return (o.x-a.x)/(b.x-a.x);
    }
    double PolygonUnion() {
        int M,c1,c2;
        double s1,s2,ret=0;
        for (int i=0; i<N; i++) {
            for (int ii=0; ii<P[i].n; ii++) {
                M=0;
                s[M++]=mp(0.00,0);
                s[M++]=mp(1.00,0);
                for (int j=0; j<N; j++) if (i!=j)
                        for (int jj=0; jj<P[j].n; jj++) {
                            c1=cmp(cross(P[i][ii],P[i][ii+1],P[j][jj]));
                            c2=cmp(cross(P[i][ii],P[i][ii+1],P[j][jj+1]));
                            if (c1==0 && c2==0) {
                                if (((P[i][ii+1]-P[i][ii])^(P[j][jj+1]-P[j][jj]))>0 && i>j) {
                                    s[M++]=mp(seg(P[j][jj],P[i][ii],P[i][ii+1]),1);
                                    s[M++]=mp(seg(P[j][jj+1],P[i][ii],P[i][ii+1]),-1);
                                }
                            } else {
                                s1=cross(P[j][jj],P[j][jj+1],P[i][ii]);
                                s2=cross(P[j][jj],P[j][jj+1],P[i][ii+1]);
                                if (c1>=0 && c2<0) s[M++]=mp(s1/(s1-s2),1);
                                else if (c1<0 && c2>=0) s[M++]=mp(s1/(s1-s2),-1);
                            }
                        }
                sort(s,s+M);
                double pre=min(max(s[0].x,0.0),1.0),now;
                double sum=0;
                int cov=s[0].y;
                for (int j=1; j<M; j++) {
                    now=min(max(s[j].x,0.0),1.0);
                    if (!cov) sum+=now-pre;
                    cov+=s[j].y;
                    pre=now;
                }
                ret+=P[i][ii]*P[i][ii+1]*sum;
            }
        }
        return ret/2;
    }
    void solve() {
        scanf("%d",&N);
        for (int i=0; i<N; i++) {
            scanf("%d", &P[i].n);
            P[i].input();
            ts=P[i].Area();
            if (cmp(ts<0)) {
                reverse(P[i].p,P[i].p+P[i].n);
                P[i][P[i].n]=P[i][0];
                ts=-ts;
            }
            S+=ts;
        }
        printf("%.9f %.9f\n",S, PolygonUnion());
    }
};

int main() {
//    file();
    Solver::solve();
    return 0;
}

B - Craters
求一个能保住所有圆的凸包的周长。

将每个圆一万等分成点,然后围一个凸包即可。

//#define backup
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const double eps = 1e-8;
const double pi = acos(-1.0);
int dcmp(double x) { if(fabs(x)<=eps) return 0; return (x>0)?1:-1;};
typedef long long LL;
void umax(LL &a, LL b) { a = max(a, b);}
void umin(LL &a, LL b) { a = min(a, b);}
#ifdef backup
cccc
#endif // backup

/*33+x
29+x
*/
void file() {
    freopen("out.txt", "r", stdin);
    freopen("1.txt", "w", stdout);
}

namespace solver {
    struct point {
        double x, y;
        bool operator < (const point & b) const {
            return y < b.y || (y == b.y && x < b.x);
        }
    }pnt[10000*200+10], res[10000*200+10];
    double mult(point sp, point ep, point op) {
        return (sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y);
    }
    int graham(point pnt[], int n, point res[]) {
        sort(pnt, pnt + n);
        if(n == 0) return 0; res[0] = pnt[0];
        if(n == 1) return 1; res[1] = pnt[1];
        if(n == 2) return 2; res[2] = pnt[2];
        int top = 1;
        for(int i = 2; i < n; i++) {
            while(top && mult(pnt[i], res[top], res[top-1]) >= 0) top--;
            res[++top] = pnt[i];
        }
        int len = top; res[++top] = pnt[n-2];
        for(int i = n - 3; i >= 0; i--) {
            while(top != len && mult(pnt[i], res[top], res[top-1]) >= 0)top--;
            res[++top] = pnt[i];
        }
        return top;
    }
    double dis(point a, point b) {
        return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
    }
    void solve() {
        int n;
        int cnt = 0, cnt2 = 0;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            double x, y, r;
//            scanf("%lf%lf", &x, &y);
//            pnt[cnt++] = {x, y};
            scanf("%lf%lf%lf", &x, &y, &r);
            r += 10;
            for(int j = 0; j < 10000; j++) {
                pnt[cnt++] = {x + r*cos(pi*2*(j/10000.0)), y + r*sin(pi*2*(j/10000.0))};
            }
        }
        cnt = graham(pnt, cnt, res);
//        cout<<cnt<<endl;
//        for(int i = 0; i < cnt; i++)
//            cout<<res[i].x<<" "<<res[i].y<<endl;
        double ss = 0, ss2 = 0;
//        res[cnt] = res[0];
        res[cnt] = res[0];
        for(int i = 1; i <= cnt; i++) {
            ss += dis(res[i], res[i-1]);
        }
//        ss = fabs(ss);
        printf("%.6f\n", ss);
    }
}
int main() {
//    file();
    solver::solve();
    return 0;
}

C - DRM Messages
模拟题

//#define backup
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const double eps = 1e-8;
int dcmp(double x) { if(fabs(x)<=eps) return 0; return (x>0)?1:-1;};
typedef long long LL;
void umax(LL &a, LL b) { a = max(a, b);}
void umin(LL &a, LL b) { a = min(a, b);}
#ifdef backup
cccc
#endif // backup

/*33+x
29+x
*/
void file() {
    freopen("out.txt", "r", stdin);
    freopen("1.txt", "w", stdout);
}

namespace solver {
    string str;
    int n;
    void solve() {
        cin >> str;
        n = str.size();
        int v1, v2;
        v1 = v2 = 0;
        for(int i = 0; i < str.size() / 2; i++)
            v1 += str[i] - 'A';
        for(int i = 0; i < str.size() / 2; i++)
            v2 += str[i+str.size()/2] - 'A';
        v1 %= 26, v2 %= 26;
        for(int i = 0; i <str.size()/2; i++) {
            int v = ((str[i]-'A'+v1) + ((str[i+str.size()/2]-'A'+v2))%26+26);
            putchar(v%26+'A');
        }
    }
}

int main() {
//    file();
    solver::solve();
    return 0;
}

D - Game of Throwns
拿栈模拟下。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int mod=1e9+7;
#define mem(s,v) memset(s,v,sizeof(s))
#define inf 0x3f3f3f3f
#define maxn 100010
#define pi (4*atan(1.0))
#define eps 1e-14

char s[101][10];
stack<int > stk;

int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        for(int i = 0; i < m; i++) {
            string str;
            cin >> str;
            if(str[0] == 'u') {
                int v;
                scanf("%d", &v);
                while(v--) {
                if(stk.empty()) break;
                    else stk.pop();
                }
                continue;
            }
            stringstream ss;
            ss << str;
            int val;
            ss >> val;
            stk.push(val);
        }
        int sum=0;
        while(!stk.empty()){
            int p=stk.top();
            sum+=p;
            stk.pop();
        }
        cout<<(sum%n+n)%n<<endl;
    }
    return 0;
}

E - Is-A? Has-A? Who Knowz-A?
共4种关系:
例如: a is b b is c , 那么 a is c
1. is is ,还是组成 is
2. has has ,还是组成 has
3. is has ,组成 has
4. has is ,组成 has
is has 看做边的关系,那么过 is 的就是保留原有相对关系,过 has 的就是一定变成 has
所以把每个字符串标号成节点,对每个节点进行 bfs ,从而对点与点之间的关系进行修改。

//#define backup
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const double eps = 1e-8;
int dcmp(double x) { if(fabs(x)<=eps) return 0; return (x>0)?1:-1;};
typedef long long LL;
void umax(LL &a, LL b) { a = max(a, b);}
void umin(LL &a, LL b) { a = min(a, b);}
#ifdef backup
cccc
#endif // backup

/*33+x
29+x
*/
void file() {
    freopen("out.txt", "r", stdin);
    freopen("1.txt", "w", stdout);
}

int id = 1;
map<string, int> mp;
int vis[555][555][2];
int is[555][555];
int has[555][555];

int push(string str) {
    if(mp.count(str)) return mp[str];
    mp[str] = id++;
}

void bfs(int st) {
    #define pii pair<int, int>
    #define ff first
    #define ss second
    queue<pii> q;
    vis[st][st][0] = 1;
    q.push({st, 0});
    while(!q.empty()) {
        pii x = q.front();
        q.pop();
        for(int i = 1; i < id; i++) {
            if(is[x.first][i] && !vis[st][i][x.second]) {
                vis[st][i][x.second] = 1;
                q.push({i, x.second});
            }
            if(has[x.first][i] && !vis[st][i][1]) {
                vis[st][i][1] = 1;
                q.push({i, 1});
            }
        }
    }
}

namespace solver {
    int n, m;
    void solve() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) {
            string a, b, c;
            cin >> a >> b >> c;
            push(a);
            push(c);
            if(b[0] == 'i') is[push(a)][push(c)] = 1;
            else has[push(a)][push(c)] = 1;
        }
        for(int i = 1; i < id; i++) bfs(i);
        for(int i = 1; i <= m; i++) {
            string a, b, c;
            cin >> a >> b >> c;
            push(a);
            push(c);
            if(b[0] == 'i') printf("Query %d: %s\n", i, vis[push(a)][push(c)][0]?"true":"false");
            else printf("Query %d: %s\n", i, vis[push(a)][push(c)][1]?"true":"false");
        }
    }
}

int main() {
//    file();
    solver::solve();
    return 0;
}

F - Keeping On Track
我们考虑枚举每个点作为被删除点,然后来统计第一问的答案。这个过程可以用一遍dfs,一边统计,一遍更新答案。
第二问就只要把第一问的基础上,贪心的把剩下的最大的两块合起来即可。和基本不等式的思想挺像的。

//#define backup
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const double eps = 1e-8;
int dcmp(double x) { if(fabs(x)<=eps) return 0; return (x>0)?1:-1;};
typedef long long LL;
void umax(LL &a, LL b) { a = max(a, b);}
void umin(LL &a, LL b) { a = min(a, b);}
#ifdef backup
cccc
#endif // backup

/*33+x
29+x
*/
void file() {
    freopen("out.txt", "r", stdin);
    freopen("1.txt", "w", stdout);
}

namespace solver {
    const int maxn = 10001;
    int n;
    vector<int> G[maxn];
    int sz[maxn];
    LL maxv = 0, id = 0;
    void dfs(int u, int fa) {
        sz[u] = 1;
        vector<int> V;
        int sum = 0;
        for(int i = 0; i < G[u].size(); i++) {
            int v = G[u][i];
            if(v == fa) continue;
            dfs(v, u);
            V.push_back(sz[v]);
            sum += sz[v];
            sz[u] += sz[v];
        }
        int ff = n - sum;
        V.push_back(ff);
        LL res = 0;
        LL ss = 0;
        for(int i = 0; i < V.size(); i++) {
//            cout<<V[i]<<" "<<u<<endl;
            res += ss * V[i];
            ss += V[i];
        }
        if(res > maxv) {
            maxv = res;
            id = u;
        }
    }
    void dfs2(int u, int fa) {
        sz[u] = 1;
        int sum = 0;
        for(int i = 0; i < G[u].size(); i++) {
            int v = G[u][i];
            if(v == fa) continue;
            dfs2(v, u);
            sz[u] += sz[v];
        }
    }
    void solve() {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(0, -1);
        dfs2(id, -1);
        LL ss = 0;
        vector<LL> V;
        for(int i = 0; i < G[id].size(); i++) V.push_back(sz[G[id][i]]);
        if(V.size() == 1) {
            cout<<0<<" "<<0<<endl;
        } else {
            sort(all(V));
            V[V.size()-2] += V[V.size()-1];
            LL ss = 0, res = 0;
            for(int i = 0; i < V.size() - 1; i ++) {
                res += ss * V[i];
                ss += V[i];
            }
            cout<<maxv<<" "<<res<<endl;
        }
    }
}

int main() {
//    file();
    solver::solve();
    return 0;
}

G - A Question of Ingestion
:读错题目,成了可以休息一小时从而使得胃容量变回一小时前的状态,写了个 n3 的DP。
令dp[i][j]代表当前准备吃第i个部分,已经连续吃了j次的答案是多少。
枚举休息多长时间转移即可。

//#define backup
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const double eps = 1e-8;
int dcmp(double x) { if(fabs(x)<=eps) return 0; return (x>0)?1:-1;};
typedef long long LL;
void umax(LL &a, LL b) { a = max(a, b);}
void umin(LL &a, LL b) { a = min(a, b);}
#ifdef backup
cccc
#endif // backup

/*33+x
29+x
*/
void file() {
    freopen("out.txt", "r", stdin);
    freopen("1.txt", "w", stdout);
}

namespace solver {
    int n, m;
    int dp[111][111];
    int v[111];
    int d[111];
    void solve() {
        scanf("%d%d", &n, &m);
        d[0] = m;
        for(int i = 1; i < 111; i++) d[i] = d[i-1] * 2 / 3;
        for(int i = 1; i <= n; i++) scanf("%d", &v[i]);
        for(int i = 1; i <= n; i++)
            dp[i][0] = min(v[i], d[0]);
        for(int i = 1; i <= n; i++) {
            for(int j = 0; j <= n; j++) {
                for(int k = 1; k + i <= n && k <= 2; k++) {
                    if(j + 2 - k >= 0)
                        dp[i+k][j+2-k] = max(dp[i+k][j+2-k], dp[i][j] + min(v[i+k], d[j+2-k]));
                }
                dp[i+3][0] = max(dp[i+3][0], dp[i][j] + min(v[i+3], m));
            }
        }
        int ans = 0;
        for(int i = 1; i <= n; i++)
            for(int j = 0; j <= n; j++) ans = max(ans, dp[i][j]);
        cout<<ans;
    }
}

int main() {
//    file();
    solver::solve();
    return 0;
}

H - Sheba’s Amoebas
说了是简单环了,直接dfs或者并查集都可以。

//#define backup
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const double eps = 1e-8;
int dcmp(double x) { if(fabs(x)<=eps) return 0; return (x>0)?1:-1;};
typedef long long LL;
void umax(LL &a, LL b) { a = max(a, b);}
void umin(LL &a, LL b) { a = min(a, b);}
#ifdef backup
cccc
#endif // backup

/*33+x
29+x
*/
void file() {
    freopen("out.txt", "r", stdin);
    freopen("1.txt", "w", stdout);
}

namespace solver {
    int n, m;
    char str[111][111];
    int fa[11111];
    int walk[8][2] = {{-1,0},{0,1},{1,0},{0,-1}, {1,1}, {1,-1},{-1,1},{-1,-1}};
    int getid(int x, int y) {
        return x*m + y;
    }
    int find(int x) {
        return fa[x] == x?x:fa[x] = find(fa[x]);
    }
    void solve() {
        for(int i = 0;  i< 11111; i++) fa[i] = i;
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
                scanf(" %c", &str[i][j]);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++) {
                int pos = getid(i, j);
                for(int k = 0; k < 8; k++) {
                    int nx = i + walk[k][0];
                    int ny = j + walk[k][1];
                    int newpos = getid(nx, ny);
                    if(str[i][j] == '#' && str[nx][ny] == '#') {
                        int f1 = find(pos);
                        int f2 = find(newpos);
                        if(f1 == f2) continue;
                        fa[f1] = f2;
                    }
                }
            }
        int cnt = 0;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
                if(find(getid(i, j)) == getid(i, j) && str[i][j] == '#')
                    cnt++;
        cout<<cnt;
    }
}

int main() {
//    file();
    solver::solve();
    return 0;
}

I - Twenty Four, Again
先dfs出交换的结果和交换的代价,然后枚举运算符。
之后手动讨论出所有括号的情况….
用逆波兰表达式计算即可…
真是蠢到不行

#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const double pi = acos(-1.0);

typedef long long LL;
typedef unsigned long long ULL;
void umax(int &a, int b) {
    a = max(a, b);
}
void umin(int &a, int b) {
    a = min(a, b);
}

void file() {
    freopen("input1.txt", "r", stdin);
//    freopen("1.txt", "w", stdout);
}
/*

*/

namespace Solver {
    int toNum(char*s, int &k) {
        int x = 0.0;
        while (s[k] >= '0'&&s[k] <= '9') {
            if (s[k] >= '0'&&s[k] <= '9')
                    x = x * 10 + s[k] - '0';
            k = k + 1;
        }
        return x;
    }

    int priority(char c) {
        int k;
        switch (c) {
            case '*':k = 2; break;
            case '/':k = 2; break;
            case '+':k = 1; break;
            case '-':k = 1; break;
            case '(':k = 0; break;
            case ')':k = 0; break;
            default:k = -1; break;
        }
        return k;
    }

    int cal(string str) {
//        cout<<str<<endl;
        char s[111];
        for(int i = 0; i <= str.size(); i++) s[i] = str[i];
        stack<int> sv;
        stack<char> sp;
        char c;
        int k = 0, flag = 1;
        int x, y;
        sp.push('\0');
        c = s[k];
        while (flag) {
            if (c >= '0'&&c <= '9') {
                sv.push(toNum(s, k));
            }
            else if (c == '\0'&& sp.top() == '\0')
                flag = 0;
            else if (c == '(' || (priority(c) > priority(sp.top())))
                sp.push(c), k++;
            else if (c == ')'&& sp.top() == '(')
                sp.pop(), k++;
            else if (priority(c) <= priority(sp.top())) {
                x = sv.top();
                sv.pop();
                if(sv.empty()) y = 0;
                else {
                    y = sv.top();
                    sv.pop();
                }
                c = sp.top();
                sp.pop();
                switch (c) {
                    case '+':y = x + y; break;
                    case '-':y = y - x; break;
                    case '*':y = x*y; break;
                    case '/':
                        if(x == 0) return 1e9;
                        if(y % x == 0)
                            y = y / x;
                        else
                            return 1e9;
                        break;
                }
                sv.push(y);
            }
            c = s[k];
        }
        return sv.top();
    }

    string x = "+-*/";
    map<vector<string>, int> mp;
    vector<string> str;
    void dfs(int pos, int x, int dep) {
        if(dep == x) {
            if(mp.count(str)) mp[str] = min(mp[str], dep);
            else mp[str] = dep;
            return ;
        }
        if(pos == str.size() - 1) return ;
        swap(str[pos], str[pos + 1]);
        dfs(0, x + 1, dep);
        swap(str[pos], str[pos + 1]);
        dfs(pos + 1, x, dep);
    }
    vector<string> G;
    void solve() {
        for(int i = 0; i < 4; i++) {
            string tmp;
            cin >> tmp;
            str.push_back(tmp);
        }
        int res = 1e9;
        for(int i = 0; i <= 6; i++)
            dfs(0, 0, i);
        G.resize(4);
        for(auto it : mp) {
            int ans = 1e9;
//            for(int i = 0; i < G.size(); i++)   cout<<G[i]<<' ';
//        puts("");
//            cout<<it.first<<" "<<it.second<<endl;
            for(int i = 0; i < 4; i++) {
                G[i] = it.first[i];
            }
            for(int i = 0; i < 4; i++)
                for(int j = 0; j < 4; j++)
                    for(int k = 0; k < 4; k++) {
                        string str;
//00
str.clear();
str += G[0]; str += x[i]; str += G[1]; str += x[j]; str += G[2]; str += x[k]; str += G[3];
if(cal(str) == 24) ans = min(ans, 0);
//11
str.clear();
str += '('; str += G[0]; str += x[i]; str += G[1]; str += ')'; str += x[j]; str += G[2]; str += x[k]; str += G[3];
if(cal(str) == 24) ans = min(ans, 1);
//22
str.clear();
str += '('; str += G[0]; str += x[i]; str += G[1]; str += x[j]; str += G[2]; str += ')'; str += x[k]; str += G[3];
if(cal(str) == 24) ans = min(ans, 1);
//33
str.clear();
str += '('; str += '('; str += G[0]; str += x[i]; str += G[1]; str += ')'; str += x[j]; str += G[2]; str += ')'; str += x[k]; str += G[3];
if(cal(str) == 24) ans = min(ans, 2);
//44
str.clear();
str += '(';  str += G[0]; str += x[i]; str += '('; str += G[1];  str += x[j]; str += G[2]; str += ')'; str += ')'; str += x[k]; str += G[3];
if(cal(str) == 24) ans = min(ans, 2);
//55
str.clear();
str += '('; str += G[0]; str += x[i]; str += G[1]; str += ')'; str += x[j]; str += '('; str += G[2]; str += x[k]; str += G[3]; str += ')';
if(cal(str) == 24) ans = min(ans, 2);
//66
str.clear();
str += G[0]; str += x[i];str += '('; str += G[1]; str += x[j]; str += G[2];str += ')';  str += x[k]; str += G[3];
if(cal(str) == 24) ans = min(ans, 1);
//77
str.clear();
str += G[0]; str += x[i];str += '('; str += G[1]; str += x[j]; str += G[2];  str += x[k]; str += G[3]; str += ')';
if(cal(str) == 24) ans = min(ans, 1);
//88
str.clear();
str += G[0]; str += x[i];str += '('; str += '('; str += G[1]; str += x[j]; str += G[2]; str+=')'; str += x[k]; str += G[3]; str += ')';
if(cal(str) == 24) ans = min(ans, 2);
//99
str.clear();
str += G[0]; str += x[i];str += '(';  str += G[1]; str += x[j];str += '('; str += G[2];  str += x[k]; str += G[3]; str += ')';str+=')';
if(cal(str) == 24) ans = min(ans, 2);
//10
str.clear();
str += G[0]; str += x[i]; str += G[1]; str += x[j]; str += '('; str += G[2]; str += x[k]; str += G[3]; str += ')';
if(cal(str) == 24) ans = min(ans, 1);
                    }
            ans += it.second * 2;
            res = min(res, ans);
        };
        if(res == 1e9) puts("impossible");
        else  cout<<res;
    };
}


int main() {
//    file();
    Solver::solve();
    return 0;
}

J - Workout for a Dumbbell
比较繁琐的模拟,要点在于每次到了一个新的器材的位置,根据时间来计算出当前这个器材上有没有人在用。
每次讨论完都要把时间推到当前人准备运动的状态。

//#define backup
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const double eps = 1e-8;
int dcmp(double x) { if(fabs(x)<=eps) return 0; return (x>0)?1:-1;};
typedef long long LL;
void umax(LL &a, LL b) { a = max(a, b);}
void umin(LL &a, LL b) { a = min(a, b);}
#ifdef backup
cccc
#endif // backup

/*33+x
29+x
*/
void file() {
    freopen("out.txt", "r", stdin);
    freopen("1.txt", "w", stdout);
}

namespace solver {
    int wou[11], wor[11], now = 0;
    int u[11], r[11], wait[11];
    void solve() {
        for(int i = 1; i <= 10; i++) scanf("%d%d", &wou[i], &wor[i]);
        for(int i = 1; i <= 10; i++) scanf("%d%d%d", &u[i], &r[i], &wait[i]);
        for(int i = 1; i <= 30; i++) {
            int j = (i % 10 == 0?10:i%10);
            if(now >= wait[j]) {
                int v = now - wait[j];
                v = v / (u[j]+r[j]) * (u[j]+r[j]);
                wait[j] += v;
                wait[j] += u[j];
                now = max(now, wait[j]);
                wait[j] += r[j];
            }
            now += wou[j];
            wait[j] = max(wait[j], now);
            now += wor[j];
        }
        cout<<now - wor[10];
    }
}

int main() {
//    file();
    solver::solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/meopass/article/details/79855299