LCCUP'21春季编程大赛-团队赛(4.10)

1. 蓄水

图片说明
图片说明
图片说明

2. 二叉树染色

图片说明
图片说明
图片说明

3. 电动车游城市

图片说明
图片说明
图片说明

4. 最多牌组数

图片说明
图片说明

5. 最小矩形面积

图片说明
图片说明

6. 守卫城堡

图片说明
图片说明
图片说明
图片说明
图片说明

答案

1. 蓄水

第一名答案

class Solution {
public:
    int storeWater(vector<int>& bucket, vector<int>& vat) {
        int ans=1e9;
        if(*max_element(vat.begin(),vat.end())==0)return 0;
        for(int i=1;i<=10000;++i){
            int n=vat.size(),sum=i;
            for(int j=0;j<n;++j){
                sum+=max(0,(vat[j]+i-1)/i-bucket[j]);
            }
            ans=min(ans,sum);
        }
        return ans;
    }
};

第二名答案

class Solution {
public:
    int storeWater(vector<int>& b, vector<int>& v) {
        int n = b.size();
        if (count(v.begin(), v.end(), 0) == n){
            return 0;
        }

        int ans = 100000000;
        for (int i = 1; i <= 10000; ++i){
            int s = i;
            for (int j = 0; j < n; ++j)
                s += max(0, (v[j] + i - 1) / i - b[j]);
            ans = min(ans, s);
        }
        return ans;
    }
};

第三名答案

2. 二叉树染色

第一名答案

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> dfs(TreeNode* root, int k){
        if (root==NULL){
            vector<int> res;
            res.push_back(0);
            return res;
        }
        vector<int> vl=dfs(root->left ,k);
        vector<int> vr=dfs(root->right ,k);
        vector<int> res;
        res.resize(k+1);
        for (int i=0;i<vl.size();i++)
            for (int j=0;j<vr.size();j++){
                res[0]=max(res[0],vl[i]+vr[j]);
                if (i+j+1<=k)
                    res[i+j+1]=max(res[i+j+1],vl[i]+vr[j]+root->val);
            }
        return res;
    }
    int maxValue(TreeNode* root, int k) {
        vector<int> result=dfs(root,k);
        int ans=0;
        for (int i=0;i<=result.size();i++)
            if (i<=k) ans=max(ans,result[i]);
        return ans;
    }
};

第二名答案

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> dfs(TreeNode* now, int k) {
        if (now->left == nullptr && now->right == nullptr) {
            vector<int> ans(k + 1, 0);
            ans[0] = 0;
            ans[1] = now->val;
            return ans;
        }
        if (now->left == nullptr) {
            vector<int> ret = dfs(now->right, k);
            vector<int> ans(k + 1, 0);
            for (int i = 0; i < k; i++) {
                ans[i + 1] = ret[i] + now->val;
                ans[0] = max(ans[0], ret[i]);
            }
            ans[0] = max(ans[0], ret[k]);
            return ans;
        }
        if (now->right == nullptr) {
            vector<int> ret = dfs(now->left, k);
            vector<int> ans(k + 1, 0);
            for (int i = 0; i < k; i++) {
                ans[i + 1] = ret[i] + now->val;
                ans[0] = max(ans[0], ret[i]);
            }
            ans[0] = max(ans[0], ret[k]);
            return ans;
        }
        vector<int> r1 = dfs(now->left, k);
        vector<int> r2 = dfs(now->right, k);
        vector<int> ans(k + 1, 0);
        int p = 0, q = 0;
        for (int i = 0; i <= k; i++) {
            p = max(p, r1[i]);
            q = max(q, r2[i]);
        }
        ans[0] = p + q;
        for (int i = 0; i <= k; i++) {
            for (int j = 0; j + i < k; j++) {
                ans[i + j + 1] = max(ans[i + j + 1], r1[i] + r2[j] + now->val);
            }
        }
        // cout << " ?? " << now->val << endl;
        // for (auto &x : r1) cout << x << ' '; cout << endl;
        // for (auto &x : r2) cout << x << ' '; cout << endl;
        // for (auto &x : ans) cout << x << ' '; cout << endl;
        return ans;
    }
    int maxValue(TreeNode* root, int k) {
        if (root == nullptr) return 0;
        vector<int> res = dfs(root, k);
        int ans = 0;
        for (auto &x : res) ans = max(ans, x);
        return ans;
    }
};

第三名答案

class Solution {
public:
    int K;
    struct Data{
        int a[2][20];
        Data(){
            memset(a,0,sizeof(a));
        }
    };
    Data dfs(TreeNode* root){
        if(!root){
            return Data();
        }
        Data ret;
        Data lres=dfs(root->left);
        Data rres=dfs(root->right);
        for(int s=0;s<2;++s){
            for(int i=0;i<=K;++i)ret.a[s][i]=-5e8;
            if(s==0){
                int mx1=0,mx2=0;
                for(int i=0;i<=K;++i)mx1=max(mx1,lres.a[0][i]),mx1=max(mx1,lres.a[1][i]);
                for(int i=0;i<=K;++i)mx2=max(mx2,rres.a[0][i]),mx2=max(mx2,rres.a[1][i]);
                ret.a[0][0]=mx1+mx2;
            } else {
                for(int i=0;i<=K;++i)
                    for(int j=0;i+j<=K;++j){
                        int L=lres.a[1][i],R=rres.a[1][j];
                        L=max(L,lres.a[0][i]),R=max(R,rres.a[0][j]);
                     //  printf("[%d,%d(%d,%d)]",L,R,root->val,i+j);
                        ret.a[1][i+j+1]=max(ret.a[1][i+j+1],L+R+root->val);
                    }
            }
        }
        return ret;
    }
    int maxValue(TreeNode* root, int k) {
        K=k;
        Data ans=dfs(root);
        int mx=0;
        for(int i=0;i<2;++i)for(int j=0;j<=K;++j)
            mx=max(mx,ans.a[i][j]);
        return mx;
    }
};

3. 电动车游城市

第一名答案

class Solution {
public:
    int f[110][110],dis[110][110];
    set<pair<int,int> > s;
    struct node{int to,next;}e[2010];
    void upd(int x,int y,int d)
    {
        if (dis[x][y]<=d&&d<1000000000) return;
        s.erase(make_pair(dis[x][y],x*1000+y));
        dis[x][y]=d;
        s.insert(make_pair(dis[x][y],x*1000+y));
    }
    int electricCarPlan(vector<vector<int>>& paths, int cnt, int start, int end, vector<int>& charge) {
        int n=charge.size(),m=paths.size(),c=0;
        for (int i=0; i<n; i++)
            for (int j=0; j<n; j++) f[i][j]=cnt*n*10;
        for (int i=0; i<m; i++) f[paths[i][0]][paths[i][1]]=min(f[paths[i][0]][paths[i][1]],paths[i][2]);
        for (int i=0; i<n; i++)
        {
            f[i][i]=0;
            for (int j=0; j<n; j++) f[i][j]=min(f[i][j],f[j][i]);
        }
        for (int k=0; k<n; k++)
            for (int i=0; i<n; i++)
                for (int j=0; j<n; j++)
                    f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
        s.clear();
        for (int i=0; i<n; i++) 
            for (int j=0; j<=cnt; j++) upd(i,j,1000000000);
        upd(start,0,0);
        while (1)
        {
            int x=(*s.begin()).second/1000,y=(*s.begin()).second%1000;
            if (x==end) return dis[x][y];
            s.erase(s.begin());
            if (y<cnt) upd(x,y+1,dis[x][y]+charge[x]);
            for (int i=0; i<n; i++) if (f[x][i]<=y)  upd(i,y-f[x][i],dis[x][y]+f[x][i]);
        }
    }
};

第二名答案

const int MAXN = 222;

struct pt {
    int u, crg; //, tm;
};

// bool operator < (const pt & a, const pt & b) {
//     return a.tm > b.tm;
// }

typedef pair<int,int> PII;

int f[MAXN][MAXN], vis[MAXN][MAXN];
vector<PII> E[MAXN];
int dis[MAXN][MAXN];
const int INF = 1e9 + 7;

class Solution {
public:
    int electricCarPlan(vector<vector<int>>& path, int cnt, int start, int end, vector<int>& charge) {
        int n = charge.size();
        for (int i = 0; i < n; i++) {
            E[i].clear();
            for (int j = 0; j <= cnt; j++) f[i][j] = INF, vis[i][j] = 0;
            // for (int j = 0; j < n; j++) dis[i][j] = INF;
        }
        for (auto &e : path) {
            E[e[0]].emplace_back(e[1], e[2]);
            E[e[1]].emplace_back(e[0], e[2]);
            // dis[e[0]][e[1]] = dis[e[1]][e[0]] = min(dis[e[1]][e[0]], e[2]);
        }
        // for (int k = 0; k < n; k++) {
        //     for (int i = 0; i < n; i++) {
        //         for (int j = 0; j < n; j++) {
        //             dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
        //         }
        //     }
        // }
        f[start][0] = 0;
        vis[start][0] = 1;
        queue<pt> Q;
        Q.push((pt){start, 0});
        while (!Q.empty()) {
            auto nico = Q.front();
            int u = nico.u;
            int crg = nico.crg;
            Q.pop();
            vis[u][crg] = 0;
            for (int i = crg + 1; i <= cnt; i++) {
                if (f[u][i] > f[u][crg] + charge[u] * (i - crg)) {
                    f[u][i] = f[u][crg] + charge[u] * (i - crg);
                    if (!vis[u][i]) {
                        vis[u][i] = 1;
                        Q.push((pt){u, i});
                    }
                }
            }
            for (auto &x : E[u]) {
                int y = x.first;
                int rm = crg - x.second;
                if (rm >= 0 && f[y][rm] > f[u][crg] + x.second) {
                    f[y][rm] = f[u][crg] + x.second;
                    if (!vis[y][rm]) {
                        vis[y][rm] = 1;
                        Q.push((pt){y, rm});
                    }
                }
            }
        }
        int ans = INF;
        for (int j = 0; j <= cnt; j++) {
            ans = min(ans, f[end][j]);
        }
        return ans;
    }
};

第三名答案

class Solution {
public:
    int electricCarPlan(vector<vector<int>>& paths, int cnt, int start, int end, vector<int>& charge) {
int n = charge.size();
  int m = paths.size();
  vector<vector<pair<int, int> > > G(n, vector<pair<int, int> > (0));
  for (int i = 0; i < m; i++) {
    G[paths[i][0]].push_back(make_pair(paths[i][2], paths[i][1]));
    G[paths[i][1]].push_back(make_pair(paths[i][2], paths[i][0]));
  }
  vector<vector<int> > dis(n, vector<int> (cnt + 1, 0x3f3f3f3f));
  dis[start][0] = 0;
  priority_queue<pair<int, pair<int, int> > > q;
  q.push(make_pair(0, make_pair(start, 0)));
  while (!q.empty()) {
    auto x = q.top();
    int d = -x.first;
    int u = x.second.first, v = x.second.second;
    q.pop();
    if (d != dis[u][v]) continue;
    if (v != cnt) {
      if (dis[u][v + 1] > dis[u][v] + charge[u]) {
        dis[u][v + 1] = dis[u][v] + charge[u];
        q.push(make_pair(-dis[u][v + 1], make_pair(u, v + 1)));
      }
    }
    for (auto y : G[u]) {
      if (v >= y.first) {
        if (dis[y.second][v - y.first] > dis[u][v] + y.first) {
          dis[y.second][v - y.first] = dis[u][v] + y.first;
          q.push(make_pair(-dis[y.second][v - y.first], make_pair(y.second, v - y.first)));
        }
      }
    }
  }
return dis[end][0];
    }
};

4. 最多牌组数

第一名答案

class Solution {
public:
    int dp[2][3][3];
    int maxGroupNumber(vector<int>& tiles) {
        int last=-1;
        bool d=0;
        map<int,int> cnt;
        for(auto x:tiles)++cnt[x];
        for(auto pr:cnt){
            int x=pr.first,c=pr.second;
            if(x-last>1){
                for(int i=0;i<3;++i)
                    for(int j=0;j<3;++j)
                        if(i+j)
                        dp[d][i][j]=-1e9;
            }
            last=x;
            x=c;
            d^=1;
            for(int i=0;i<3;++i)
                    for(int j=0;j<3;++j)
                        dp[d][i][j]=-1e9;
            for(int c3=0;c3<=min(2,x);++c3)
                for(int c2=0;c2<=min(2,x-c3);++c2)
                    for(int c1=0;c1<=min(2,x-c2-c3);++c1)
                    {
                        dp[d][c1][c2]=max(dp[d][c1][c2],dp[d^1][c2][c3]+c3+(x-c1-c2-c3)/3);
                    }
        }
        return dp[d][0][0];
    }
};

第二名答案

int dp[2][5][5];

class Solution {
public:
    int maxGroupNumber(vector<int>& t) {
        map<int, int> lst;
        for (auto x: t)
            ++lst[x];

        memset(dp, -1, sizeof(dp));
        dp[0][0][0] = 0;
        int ri = 0;
        int pre[2] = {-2, -1};
        for (auto pr: lst){
            int x = pr.first, c = pr.second;
            auto (&f) = dp[ri & 1];
            auto (&g) = dp[ri + 1 & 1];
            ri += 1;

            memset(g, -1, sizeof(g));
            for (int i = 0; i <= 2; ++i){
                if (c < i) continue;
                if (i > 0 && !(pre[0] + 1 == pre[1] && pre[1] + 1 == x)) continue;
                for (int j = i; j <= 4; ++j)
                    for (int k = i; k <= 4; ++k){
                        if (f[j][k] == -1) continue;
                        int tc = c - i;
                        for (int l = 0; l <= 4 && tc >= l; ++l)
                            g[k - i][l] = max(g[k - i][l], f[j][k] + i + (tc - l) / 3);
                        //printf("%d %d %d %d, %d %d\n", i, j, k, g[0][0], tc, f[j][k]);
                    }
            }
            for (int j = 4; j >= 0; --j)
                for (int k = 4; k >= 0; --k){
                    if (j > 0) g[j - 1][k] = max(g[j - 1][k], g[j][k]);
                    if (k > 0) g[j][k - 1] = max(g[j][k - 1], g[j][k]);
                }

            pre[0] = pre[1];
            pre[1] = x;
        }

        return dp[ri & 1][0][0];
    }
};

第三名答案

class Solution {
public:
    int maxGroupNumber(vector<int>& tiles) {
int n = tiles.size();
  map<int, int> c;
  int f[3][3], g[3][3];
  for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) f[i][j] = g[i][j] = 0;
  for (int i = 0; i < n; i++) {
    c[tiles[i]]++;
  }
  int las = -4, cur;
  for (auto x : c) {
    cur = x.first;
    if (cur == las + 1) {
      for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
          for (int k = 0; k < 3; k++) {
            if (i + j + k > (c.count(cur)?c[cur]:0)) continue;
            if (j + k > (c.count(cur+1)?c[cur+1]:0)) continue;
            if (k > (c.count(cur+2)?c[cur+2]:0)) continue;
            g[j][k] = max(g[j][k], f[i][j] + k + ((int) (c.count(cur)?c[cur]:0) - i - j - k) / 3);
          }
        }
      }
    } else {
      for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
          for (int k = 0; k < 3; k++) {
            if (k > (c.count(cur)?c[cur]:0)) continue;
            if (k > (c.count(cur+1)?c[cur+1]:0)) continue;
            if (k > (c.count(cur+2)?c[cur+2]:0)) continue;
            g[0][k] = max(g[0][k], f[i][j] + k + ((int) (c.count(cur)?c[cur]:0) - k) / 3);
          }
        }
      }
    }
    for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {
      f[i][j] = g[i][j];
      g[i][j] = 0;
    }
    las = cur;
  }
  int ans = 0;
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
      ans = max(ans, f[i][j]);
    }
  }
        return ans;
    }
};

5. 最小矩形面积

第一名答案

bool cmp1(const vector<int> &a,const vector<int> &b){
    return a[0]==b[0]?a[1]>b[1]:a[0]<b[0];
}

bool cmp2(const vector<int> &a,const vector<int> &b){
    return a[0]==b[0]?a[1]>b[1]:a[0]>b[0];
}


class Solution {
public:

    double solve1(vector<vector<int> >& lines){
        double p=1e18;
        sort(lines.begin(),lines.end(),cmp1);
        for (int i=1;i<lines.size();i++)
            if (lines[i][0]!=lines[i-1][0]){
                double px=-(lines[i][1]-lines[i-1][1])*1.0/(lines[i][0]-lines[i-1][0]);
                p=min(p,px);
            }
        return p;
    }


    double solve2(vector<vector<int> >& lines){
        double p=-1e18;
        sort(lines.begin(),lines.end(),cmp2);
        for (int i=1;i<lines.size();i++)
            if (lines[i][0]!=lines[i-1][0]){
                double px=-(lines[i][1]-lines[i-1][1])*1.0/(lines[i][0]-lines[i-1][0]);
                p=max(p,px);
            }
        return p;
    }


    double solve3(vector<vector<int> >& lines){
        double p=1e18;
        sort(lines.begin(),lines.end(),cmp1);
        for (int i=1;i<lines.size();i++)
            if (lines[i][0]!=lines[i-1][0]){
                double px=-(lines[i][1]-lines[i-1][1])*1.0/(lines[i][0]-lines[i-1][0]);
                double py=px*lines[i][0]+lines[i][1];
                p=min(p,py);
            }
        return p;
    }


    double solve4(vector<vector<int> >& lines){
        double p=-1e18;
        sort(lines.begin(),lines.end(),cmp2);
        for (int i=1;i<lines.size();i++)
            if (lines[i][0]!=lines[i-1][0]){
                double px=-(lines[i][1]-lines[i-1][1])*1.0/(lines[i][0]-lines[i-1][0]);
                double py=px*lines[i][0]+lines[i][1];
                p=max(p,py);
            }
        return p;
    }
    double minRecSize(vector<vector<int> >& lines) {
        bool flag=0;
        for (auto i:lines)
            if (i[0]!=lines.back()[0])
                flag=1;
        if (!flag)
            return 0;
        double v1=solve1(lines);
        double v2=solve2(lines);
        double v3=solve3(lines);
        double v4=solve4(lines);
          return (v2-v1)*(v4-v3);
    }
};

第二名答案

typedef long long ll;

class Solution {
public:
    double minRecSize(vector<vector<int>>& f) {
        int n = f.size();
        vector<ll> k(n, 0), b(n, 0);
        sort(f.begin(), f.end());
        double ans = 0;
        for (int i = 0; i < n; i++) {
            k[i] = f[i][0];
            b[i] = f[i][1];
        }
        int p = 0, q = 0;
        while (q < n && k[q] == k[p]) q++;
        if (q >= n) return 0.;
        double x_min = 1e100, x_max = -1e100;
        double y_min = 1e100, y_max = -1e100;
        for (; q < n;) {
            int r = q;
            while (r + 1 < n && k[r + 1] == k[q]) r++;
            // [p, q - 1], [q, r]
            double cx1 = 1.0 * (b[r] - b[p]) / (k[r] - k[p]);
            double cx2 = 1.0 * (b[q] - b[q - 1]) / (k[q] - k[q - 1]);
            x_min = min(x_min, min(cx1, cx2));
            x_max = max(x_max, max(cx1, cx2));
            double cy1 = 1.0 * (b[r] * k[p] - b[p] * k[r]) / (k[r] - k[p]);
            double cy2 = 1.0 * (b[q] * k[q - 1] - b[q - 1] * k[q]) / (k[q] - k[q - 1]);
            y_min = min(y_min, min(cy1, cy2));
            y_max = max(y_max, max(cy1, cy2));
            p = q;
            while (q < n && k[q] == k[p]) q++;
        }
        return (x_max - x_min) * (y_max - y_min);
    }
};

第三名答案

#include<bits/stdc++.h>

#define min min111
#define max max111

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef double lf;
typedef long double llf;
typedef std::pair<int,int> pii;

#define xx first
#define yy second

template<typename T> inline T max(T a,T b){return a>b?a:b;}
template<typename T> inline T min(T a,T b){return a<b?a:b;}
template<typename T> inline T abs(T a){return a>0?a:-a;}
template<typename T> inline bool repr(T &a,T b){return a<b?a=b,1:0;}
template<typename T> inline bool repl(T &a,T b){return a>b?a=b,1:0;}
template<typename T> inline T gcd(T a,T b){T t;if(a<b){while(a){t=a;a=b%a;b=t;}return b;}else{while(b){t=b;b=a%b;a=t;}return a;}}
template<typename T> inline T sqr(T x){return x*x;}
#define mp(a,b) std::make_pair(a,b)
#define pb push_back
#define I __attribute__((always_inline))inline
#define mset(a,b) memset(a,b,sizeof(a))
#define mcpy(a,b) memcpy(a,b,sizeof(a))

#define fo0(i,n) for(int i=0,i##end=n;i<i##end;i++)
#define fo1(i,n) for(int i=1,i##end=n;i<=i##end;i++)
#define fo(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define fd0(i,n) for(int i=(n)-1;~i;i--)
#define fd1(i,n) for(int i=n;i;i--)
#define fd(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define foe(i,x)for(__typeof((x).end())i=(x).begin();i!=(x).end();++i)
#define fre(i,x)for(__typeof((x).rend())i=(x).rbegin();i!=(x).rend();++i)

#ifdef LOCAL
struct Cg{I char operator()(){return getchar();}};
struct Cp{I void operator()(char x){putchar(x);}};
#define OP operator
#define RT return *this;
#define UC unsigned char
#define RX x=0;UC t=P();while((t<'0'||t>'9')&&t!='-')t=P();bool f=0;\
if(t=='-')t=P(),f=1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f)x=-x
#define RU x=0;UC t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define TR *this,x;return x;
I bool IS(char x){return x==10||x==13||x==' ';}template<typename T>struct Fr{T P;I Fr&OP,(int&x)
{RX;if(f)x=-x;RT}I OP int(){int x;TR}I Fr&OP,(ll &x){RX;if(f)x=-x;RT}I OP ll(){ll x;TR}I Fr&OP,(char&x)
{for(x=P();IS(x);x=P());RT}I OP char(){char x;TR}I Fr&OP,(char*x){char t=P();for(;IS(t);t=P());if(~t){for(;!IS
(t)&&~t;t=P())*x++=t;}*x++=0;RT}I Fr&OP,(lf&x){RX;RL;RT}I OP lf(){lf x;TR}I Fr&OP,(llf&x){RX;RL;RT}I OP llf()
{llf x;TR}I Fr&OP,(uint&x){RU;RT}I OP uint(){uint x;TR}I Fr&OP,(ull&x){RU;RT}I OP ull(){ull x;TR}};Fr<Cg>in;
#define WI(S) if(x){if(x<0)P('-'),x=-x;UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
#define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
#define WU(S) if(x){UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
template<typename T>struct Fw{T P;I Fw&OP,(int x){WI(10);RT}I Fw&OP()(int x){WI(10);RT}I Fw&OP,(uint x){WU(10);RT}
I Fw&OP()(uint x){WU(10);RT}I Fw&OP,(ll x){WI(19);RT}I Fw&OP()(ll x){WI(38);RT}I Fw&OP,(ull x){WU(20);RT}I Fw&OP()
(ull x){WU(20);RT}I Fw&OP,(char x){P(x);RT}I Fw&OP()(char x){P(x);RT}I Fw&OP,(const char*x){while(*x)P(*x++);RT}
I Fw&OP()(const char*x){while(*x)P(*x++);RT}I Fw&OP()(lf x,int y){WL;RT}I Fw&OP()(llf x,int y){WL;RT}};Fw<Cp>out;
#endif

using std::string;
using std::vector;

const int N=100007;

int n,cp[N];
lf k[N],b[N];
std::pair<lf,int>c[N],d[N];

void upd(lf&xmin,lf&xmax,lf k1,lf b1,lf k2,lf b2)
{
    if(abs(k1-k2)/k1<1e-6)return;
    lf u=(b1-b2)/(k2-k1);
    //printf("upd: %.5f %.5f %.5f %.5f %.5f\n",k1,b1,k2,b2,u);
    repl(xmin,u),repr(xmax,u);
}

void tsolve(lf l,lf r,lf&xmin,lf&xmax)
{
    //printf("tsolve:%.5f %.5f %.5f %.5f\n",l,r,xmin,xmax);
    fo0(i,n)c[i]=mp(l*k[i]+b[i],i),d[i]=mp(r*k[i]+b[i],i);
    std::sort(c,c+n);
    std::sort(d,d+n);
    fo0(i,n)cp[c[i].yy]=i;
    std::set<int>tmp;
    fo0(i,n)
    {
        int u=cp[d[i].yy];
        std::set<int>::iterator t=tmp.lower_bound(u);
        while(t!=tmp.end())
        {
            upd(xmin,xmax,k[d[i].yy],b[d[i].yy],k[c[*t].yy],b[c[*t].yy]);
            ++t;
        }
        tmp.insert(u);
    }
}

void solve(lf&xmin,lf&xmax)
{
    //out,"solve\n";
    // first sample n points
    std::mt19937 ran(114514);
    fo0(i,n)
    {
        int x=ran()%n,y=ran()%(n-1);
        if(y>=x)y++;
        upd(xmin,xmax,k[x],b[x],k[y],b[y]);
    }
    //tsolve(-1e15,1e10,xmin,xmax);
    tsolve(-1e20,xmin,xmin,xmax);
    tsolve(xmax,1e20,xmin,xmax);
}

void flip()
{
    fo0(i,n)
    {
        //kx+b=0
        lf nb=-b[i]/k[i];
        lf nk=1/k[i];
        k[i]=nk,b[i]=nb;
    }
}

class Solution {
public:
    double minRecSize(vector<vector<int>>& lines) {
        n=lines.size();
        fo0(i,n)k[i]=lines[i][0],b[i]=lines[i][1];
        std::set<int>ks;
        fo0(i,n)ks.insert(lines[i][0]);
        if(ks.size()==1)return 0;
        lf xmax=-1e20,xmin=1e20,ymax=-1e20,ymin=1e20;
        solve(xmin,xmax);
        flip();
        solve(ymin,ymax);
        //int i=28,j=20;upd(ymin,ymax,k[i],b[i],k[j],b[j]);
        //printf("%.5f %.5f %.5f %.5f\n",xmin,xmax,ymin,ymax);
        return (xmax-xmin)*(ymax-ymin);
    }
};

#ifdef LOCAL

class Solution2 {
public:
    double minRecSize(vector<vector<int>>& lines) {
        n=lines.size();
        fo0(i,n)k[i]=lines[i][0],b[i]=lines[i][1];
        lf xmax=-1e20,xmin=1e20,ymax=-1e20,ymin=1e20;
        //fo0(i,n)fo0(j,n)upd(xmin,xmax,k[i],b[i],k[j],b[j]);
        //flip();
        //fo0(i,n)fo0(j,n)upd(ymin,ymax,k[i],b[i],k[j],b[j]);
        fo0(i,n)fo0(j,i)
        {
            lf k1=k[i],b1=b[i],k2=k[j],b2=b[j];
            if(abs(k1-k2)<1e-6)continue;
            lf u1=1/k1,v1=-b1/k1,u2=1/k2,v2=-b2/k2;
            lf x=(b1-b2)/(k2-k1);
            lf y=x*k1+b1;
            //if(y<-2e6||y>2e6)printf("%d %d %.5f %.5f %.5f\n",i,j,x,y,(v1-v2)/(u2-u1));
            repl(xmin,x),repr(xmax,x),repl(ymin,y),repr(ymax,y);
        }
        printf("%.5f %.5f %.5f %.5f\n",xmin,xmax,ymin,ymax);
        return (xmax-xmin)*(ymax-ymin);
    }
};

int main()
{
    /*vector<int> t1({2,3});
    vector<int> t2({3,0});
    vector<int> t3({4,1});
    vector<vector<int>>t({t1,t2,t3});*/
    vector<vector<int>>t;
    fo0(T,1)
    {
        t.clear();
        fo0(i,1000)
        {
            t.pb(vector<int>({rand()%10000+1,rand()%20001-10000}));
        }
        lf a=Solution().minRecSize(t);
        lf b=Solution2().minRecSize(t);
        printf("%.5f %.5f\n",a,b);
        if(abs(a-b)>1e-4)printf("%.5f %.5f\n",a,b);
    }
    //out,Solution().purchasePlans(t,10),'\n';
    //out,Solution().orchestraLayout(3,0,2),'\n';
    //int n=9;fo0(i,n){fo0(j,n)out,Solution().orchestraLayout(n,i,j),' ';out,'\n';}
}
#endif

6. 守卫城堡

第一名答案

class Solution {
public:
    struct node{int to,next,c;}e[1000010];
    int n,dis[50010],q[50010],l,r,hd[50010],cnt,cur[50010];
    void add(int x,int y,int c)
    {
        e[++cnt]=(node){y,hd[x],c},hd[x]=cnt;
        e[++cnt]=(node){x,hd[y],0},hd[y]=cnt;
    }
    bool bfs()
    {
        for (int i=2 ;i<=n; i++) dis[i]=-1;
        dis[1]=0,q[l=r=1]=1;
        while (l<=r)
        {
            int x=q[l++];
            for (int i=hd[x]; i; i=e[i].next)
                if (dis[e[i].to]==-1&&e[i].c) q[++r]=e[i].to,dis[e[i].to]=dis[x]+1;
        }
        return dis[n]!=-1;
    }
    int dfs(int x,int f)
    {
        if (x==n) return f;
        for (int &i=cur[x]; i; i=e[i].next)
            if (dis[e[i].to]==dis[x]+1&&e[i].c)
            {
                int nw=dfs(e[i].to,min(f,e[i].c));
                if (nw) return e[i].c-=nw,e[i^1].c+=nw,nw;
            }
        return 0;
    }
    long long solve()
    {
        long long ans=0,nw;
        while (bfs())
        {
            for (int i=1; i<=n; i++) cur[i]=hd[i];
            while (nw=dfs(1,1000000000)) ans+=nw;
        }
        return ans;
    }
    int guardCastle(vector<string>& grid) {
        memset(hd,0,sizeof(hd)),cnt=1;
        int m=grid[0].length();
        n=4*m+3;
        for (int i=0; i<2; i++)
            for (int j=0; j<m; j++)
                if (grid[i][j]=='C') add(j*2+i+2,j*2+i+2+2*m,1000000000),add(j*2+i+2+2*m,4*m+3,1000000000); else
                if (grid[i][j]=='P') add(j*2+i+2,j*2+i+2+2*m,1000000000),add(j*2+i+2+2*m,4*m+2,1000000000),add(4*m+2,j*2+i+2,1000000000); else
                if (grid[i][j]=='.') add(j*2+i+2,j*2+i+2+2*m,1); else
                if (grid[i][j]=='S') add(1,j*2+i+2,1000000000),add(j*2+i+2,j*2+i+2+2*m,1000000000);
            for (int j=0; j<m; j++)
            {
                add(j*2+1+2+2*m,j*2+2,1000000000);
                add(j*2+2+2*m,j*2+1+2,1000000000);
            }
            for (int j=1; j<m; j++)
            {
                add(j*2+1+2+2*m,(j-1)*2+1+2,1000000000);
                add((j-1)*2+1+2+2*m,j*2+1+2,1000000000);
                add(j*2+2+2*m,(j-1)*2+2,1000000000);
                add((j-1)*2+2+2*m,j*2+2,1000000000);
            }
        long long ans=solve();
        if (ans>=1000000000) return -1; else return ans;
    }
};

第二名答案

class Solution {
public:
    int n;
    //    i, monster, port, castle, monster--port, castle--port
    int f[20010][4][4][4][2][2];
    void upd(int &x, int y) {
        x = min(x, y);
    }
    int guardCastle(vector<string>& grid) {
        int n = grid[0].size();
        const int INF = 1e8;
        for (int i=0;i<=n;i++) {
            for (int m=0;m<4;m++) {
                for (int p=0;p<4;p++) {
                    for (int c=0;c<4;c++) {
                        for (int mp=0;mp<2;mp++) {
                            for (int cp=0;cp<2;cp++) {
                                f[i][m][p][c][mp][cp] = INF;
                            }
                        }
                    }
                }
            }
        }
        //    i, monster, port, castle, monster--port, castle--port
        f[0][0][0][0][0][0] = 0;
        for (int i=0;i<n;i++) {
            for (int m=0;m<4;m++) {
                for (int p=0;p<4;p++) {
                    for (int c=0;c<4;c++) {
                        for (int mp=0;mp<2;mp++) {
                            for (int cp=0;cp<2;cp++) {
                                int now = f[i][m][p][c][mp][cp];
                                if (now == INF) continue;
                                int mup = (m & 1);
                                int mdown = (m >> 1);
                                int pup = (p & 1);
                                int pdown = (p >> 1);
                                int cup = (c & 1);
                                int cdown = (c >> 1);
                                /*
                                bool ok = true;
                                if (mup && grid[0][i+1] == 'C') ok = false;
                                if (mdown && grid[1][i+1] == 'C') ok = false;
                                if (cup && grid[0][i+1] == 'S') ok = false;
                                if (cdown && grid[1][i+1] == 'S') ok = false;
                                if (!ok) continue;
                                */
                                int delta = 0;
                                // how to put stone
                                bool print = (i==3&&m==0&&p==1&&c==1&&mp==0&&cp==1);
                                for (int nn=0;nn<4;nn++) {
                                    int up_stone = (nn & 1);
                                    int down_stone = (nn >> 1);
                                    int cost = __builtin_popcount(nn);
                                    if (up_stone && grid[0][i] != '.') continue;
                                    if (down_stone && grid[1][i] != '.') continue;
                                    up_stone |= (grid[0][i] == '#');
                                    down_stone |= (grid[1][i] == '#'); 
                                    int new_mup = 0, new_mdown = 0, new_pup = 0, new_pdown = 0, new_cup = 0, new_cdown = 0;
                                    int new_mp = mp, new_cp = cp;
                                    if (!up_stone) {
                                        new_mup = (grid[0][i] == 'S' || mup);
                                        new_pup = (grid[0][i] == 'P' || pup);
                                        new_cup = (grid[0][i] == 'C' || cup);
                                    }
                                    if (!down_stone) {
                                        new_mdown = (grid[1][i] == 'S' || mdown);
                                        new_pdown = (grid[1][i] == 'P' || pdown);
                                        new_cdown = (grid[1][i] == 'C' || cdown);
                                    }
                                    if (!up_stone) {
                                        new_mup |= new_mdown;
                                        new_pup |= new_pdown;
                                        new_cup |= new_cdown;
                                    }
                                    if (!down_stone) {
                                        new_mdown |= new_mup;
                                        new_pdown |= new_pup;
                                        new_cdown |= new_cup;
                                    }
                                    new_mp |= (new_mup && new_pup);
                                    new_mp |= (new_mdown && new_pdown);
                                    new_cp |= (new_cup && new_pup);
                                    new_cp |= (new_cdown && new_pdown);
                                    int new_m = new_mup + new_mdown * 2;
                                    int new_p = new_pup + new_pdown * 2;
                                    int new_c = new_cup + new_cdown * 2;
                                    //if (print) printf("%d: go %d %d %d %d %d\n",nn,new_m,new_p,new_c,new_mp,new_cp);
                                    if (new_mup && new_cup) continue;
                                    if (new_mdown && new_cdown) continue;
                                    upd(f[i + 1][new_m][new_p][new_c][new_mp][new_cp], now + cost);
                                }
                            }
                        }
                    }
                }
            }
        }
        //    i,  monster, port, castle, monster--port, castle--port
        //printf("? %d\n",f[3][0][1][1][0][1]);
        //printf("? %d\n",f[4][2][0][0][0][1]);
        int ans = INF;
        for (int m=0;m<4;m++) {
            for (int p=0;p<4;p++) {
                for (int c=0;c<4;c++) {
                    for (int mp=0;mp<2;mp++) {
                        for (int cp=0;cp<2;cp++) {
                            if (mp && cp) continue;
                            upd(ans, f[n][m][p][c][mp][cp]);
                        }
                    }
                }
            }
        }
        if (ans == INF) ans = -1;
        return ans;
    }
};

第三名答案

#ifdef yfzLOCAL
#include<bits/stdc++.h>
using namespace std;
#endif
namespace WXHAK{
    struct edge{
        int r,nxt,w;
    }e[1010000];
    int head[1001000],q[1001000],l,r,S,T,esz,cur[1010000],dep[1001000];
    void adde(int u,int v,int w){
//        printf("[%d,%d,%d]\n",u,v,w);
        e[++esz].r=v;e[esz].nxt=head[u];head[u]=esz;e[esz].w=w;
        e[++esz].r=u;e[esz].nxt=head[v];head[v]=esz;e[esz].w=0;
    }
    bool bfs(){
        for(int i=S;i<=T;++i)dep[i]=0,cur[i]=head[i];
        l=r=0,q[r++]=S,dep[S]=1;
        while(l<r){
            int u=q[l++];
            for(int t=head[u];t;t=e[t].nxt)if(e[t].w&&!dep[e[t].r])
                dep[e[t].r]=dep[u]+1,q[r++]=e[t].r;
        }
        return dep[T]!=0;
    }
    int find(int u,int flow){
        if(u==T)return flow;
        int used=0,a=0;
        for(int& t=cur[u];t;t=e[t].nxt)if(e[t].w&&dep[e[t].r]==dep[u]+1){
            a=find(e[t].r,min(flow-used,e[t].w)),e[t].w-=a,e[t^1].w+=a,used+=a;
            if(used==flow)return used;
        }
        return used;
    }
    void clr(int nS,int nT){
        for(int i=S;i<=T;++i)head[i]=0;
        S=nS,T=nT,esz=1;
    }
    int dinic(){
        int ans=0;
        while(bfs())ans+=find(S,1<<30);
        return ans;
    }
}
class Solution {
public:
    int in(int x,int y,int n){
        return (x*n+y)*2+1;
    }

    int out(int x,int y,int n){
        return (x*n+y)*2+2;
    }
    int guardCastle(vector<string>& grid) {
        int n=grid[0].size();
        WXHAK::clr(0,n*4+10);
        int S=0,T=n*4+10;
        int dx[4]={0,0,1,-1};
        int dy[4]={1,-1,0,0};
        int inf=1e9;
        int Pin=n*4+9,Pout=n*4+8;
        for(int i=0;i<2;++i){
            for(int j=0;j<n;++j){
                if(grid[i][j]=='.'&&grid[i][j]!='#'){
                    WXHAK::adde(in(i,j,n),out(i,j,n),1);
                    for(int k=0;k<4;++k){
                        int ni=i+dx[k],nj=j+dy[k];
                        if(ni>=0&&ni<2&&nj>=0&&nj<n&&grid[ni][nj]!='#'){
//                        printf("<%d,%d>--<%d,%d>\n",i,j,ni,nj);
                            WXHAK::adde(out(i,j,n),in(ni,nj,n),inf);
                        }
                    }
                } else if(grid[i][j]=='S'){
                    WXHAK::adde(S,out(i,j,n),inf);
                    for(int k=0;k<4;++k){
                        int ni=i+dx[k],nj=j+dy[k];
                        if(ni>=0&&ni<2&&nj>=0&&nj<n&&grid[ni][nj]!='#'){
                            WXHAK::adde(out(i,j,n),in(ni,nj,n),inf);
                        }
                    }
                } else if(grid[i][j]=='C'){
                    WXHAK::adde(in(i,j,n),T,inf);
                } else if(grid[i][j]=='P'){
                    WXHAK::adde(in(i,j,n),Pin,inf);
                    for(int k=0;k<4;++k){
                        int ni=i+dx[k],nj=j+dy[k];
                        if(ni>=0&&ni<2&&nj>=0&&nj<n&&grid[ni][nj]!='#'){
                            WXHAK::adde(Pin,in(ni,nj,n),inf);
                        }
                    }
                }
            }
        }
        int ans=WXHAK::dinic();
        if(ans>10*n)return -1;
        else return ans;
    }
};
#ifdef yfzLOCAL
int main(){
    vector<string> A;
//    string s;
//    cin>>s;
//    A.push_back(s);
//    cin>>s;
//    A.push_back(s);
    int n=1e4;
    srand(time(0));
    for(int i=0;i<2;++i){
        string s;
        for(int j=0;j<n;++j){
            int r=rand()%7;
            if(r<5){
                s+=rand()%10?".":"#";
            } else if(r==5){
                s+="S";
            } else s+=".";
        }
        A.push_back(s);
    }
    A[rand()%2][rand()%n]='C';
    Solution sol;
    printf("%d",sol.guardCastle(A));
}
#endif
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务