• 9.11模拟赛


    T1.dinosaur

    把(p[i],h[i])转换成一个区间[p[i]-h[i],p[i]+h[i]],考虑这些区间的关系

    1.区间相离:单独计算每个区间长度/2,取最大值

    2.区间包含:只计算大区间(实际操作中可以忽略,并入第一类)

    3.区间相交:把两个区间合并,变成一个更大的区间

    重载运算符不加const然后CE了,0分

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    
    using namespace std;
    
    typedef long long ll;
    
    inline ll rd(){
        ll ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=300005;
    
    typedef long long ll;
    
    struct Node{
        ll l,r;
        bool operator <(const Node &rhs){
            return l==rhs.l?r<rhs.r:l<rhs.l;    
        }
    }a[MAXN];
    
    ll n;
    
    int main(){
        freopen("dinosaur.in","r",stdin);
        freopen("dinosaur.out","w",stdout);
        n=rd();
        ll x,y;
        for(register int i=1;i<=n;i++){
            x=rd();y=rd();
            a[i].l = x-y;
            a[i].r = x+y;
        }
        sort(a+1,a+1+n);
        ll lstr=-1,lstl=-1;
        double ans=0.0;
        for(register int i=1;i<=n;i++){
            ll u=a[i].l,v=a[i].r;
            if(u<0) return puts("-1"),0;
            if(u>=lstr){
                ans=max(ans,1.0*(lstr-lstl)/2.0);
                lstl=u;lstr=v;
                continue;
            }
            lstr=max(lstr,v);
        }
        ans=max(ans,1.0*(lstr-lstl)/2);
        printf("%.1lf
    ",ans);
        return 0;
    }
    View Code

    T2.inter

    树剖维护一下即可

    考完了才知道有个小剪枝,就是query_link时查到有值就可以返回了,线段树上query也是一样,因为我们只关心存不存在

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    
    using namespace std;
    
    const int MAXN=131072; 
    
    inline int rd(){
      int ret=0,f=1;char c;
      while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
      while(isdigit(c))ret=ret*10+c-'0',c=getchar();
      return ret*f;
    }
    
    int n,m;
    
    struct Edge{
      int next,to;
    }e[MAXN<<1];
    int ecnt=1,head[MAXN];
    inline void adde(int x,int y){
      e[++ecnt].next = head[x];
      e[ecnt].to = y;
      head[x] = ecnt;
    }
    
    #define mid ((l+r)>>1)
    #define ls (cur<<1)
    #define rs (cur<<1|1)
    int val[MAXN*4],add[MAXN*4];
    inline void pushup(int cur){val[cur]=val[ls]+val[rs];}
    inline void pushdown(int cur,int l,int r){
      add[ls]+=add[cur];
      add[rs]+=add[cur];
      val[ls]+=add[cur]*(mid-l+1);
      val[rs]+=add[cur]*(r-mid);
      add[cur]=0;
    }
    void build(int cur,int l,int r){
      if(l==r) {return;}
      build(ls,l,mid);
      build(rs,mid+1,r);
      pushup(cur);
    }
    int query(int L,int R,int cur,int l,int r){
      if(L<=l&&r<=R) return val[cur];
      pushdown(cur,l,r);
      int ret=0;
      if(L<=mid) ret+=query(L,R,ls,l,mid);
      if(ret) return 1;
      if(mid <R) ret+=query(L,R,rs,mid+1,r);
      return ret;
    }
    void update(int L,int  R,int  cur,int  l,int  r,int  w){
      if(L<=l&&r<=R){
        (add[cur]+=w);
        (val[cur]+=w*(r-l+1));
        return;
      }
      pushdown(cur,l,r);
      if(L<=mid) update(L,R,ls,l,mid,w);
      if(mid <R) update(L,R,rs,mid+1,r,w);
      pushup(cur);
    }
    
    int fa[MAXN],dep[MAXN],hs[MAXN],siz[MAXN];
    void dfs1(int  cur,int  pre){
      fa[cur]=pre;dep[cur]=dep[pre]+1;siz[cur]=1;
      int mx=-1;
      for(register int i=head[cur];i;i=e[i].next){
        int v=e[i].to;
        if(v==pre) continue;
        dfs1(v,cur);
        siz[cur]+=siz[v];
        if(siz[v]>mx){mx=siz[v];hs[cur]=v;}
      }
    }
    int top[MAXN],id[MAXN],tim;
    void dfs2(int cur,int tp){
      id[cur]=++tim;top[cur]=tp;
      if(hs[cur]) dfs2(hs[cur],tp);
      for(register int i=head[cur];i;i=e[i].next){
        int v=e[i].to;
        if(v==fa[cur]||v==hs[cur]) continue;
        dfs2(v,v);
      }
    }
    inline int query_link(int x,int y){
      int ret=0;
      while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        ret+=query(id[top[x]],id[x],1,1,n);
        x=fa[top[x]];
        if(ret) return 1;
      }
      if(dep[x]>dep[y]) swap(x,y);
      ret+=query(id[x],id[y],1,1,n);
      return ret;
    }
    inline void update_link(int x,int y,int w){
      while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        update(id[top[x]],id[x],1,1,n,w);
        x=fa[top[x]];
      }
      if(dep[x]>dep[y]) swap(x,y);
      update(id[x],id[y],1,1,n,w);
    }
    
    int main(){
      freopen("inter.in","r",stdin);
      freopen("inter.out","w",stdout);
      n=rd();
      register int x,y,u,v;
      for(register int i=1;i<=n-1;i++){
        x=rd();
        y=rd();
        adde(x,y);
        adde(y,x);
      }
      dfs1(1,0);
      dfs2(1,1);
      build(1,1,n);
      m=rd();
      for(register int i=1;i<=m;i++){
          x=rd();y=rd();u=rd();v=rd();
          update_link(x,y,1);
          if(query_link(u,v))puts("YES");
          else puts("NO");
          update_link(x,y,-1);
      }
      return 0;
    }
    View Code

    T3.kenken

    暴力大搜索,考场上经历了这么几个剪枝:

    1.没有剪枝,甚至过不了第二个样例

    2.记录联通块当前填了的数的积cur,若是cur*pow(联通块能填的最大的数,联通块未填的数个数)<联通块标的数,则剪枝

    3.同2记录cur,若cur>连通块标的数,剪枝

    到这里就有70分了,我也是这样交的,然而memcpy没有加cstring库,本地还能编译通过...CE

    标答给了另一个角度的剪枝:

    4.从标号小的联通块开始搜索,因为它们填写的方案比较少,若标号相同则从size小的开始搜索

    //Stay foolish,stay hungry,stay young,stay simple
    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<vector> 
    using namespace std;
    
    inline int rd(){
     int ret=0,f=1;char c;
     while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
     while(isdigit(c))ret=ret*10+c-'0',c=getchar();
     return ret*f;
    }
    
    const int MAXN=128;
    
    int n;
    
    
    int num[MAXN][MAXN];
    int vaild[MAXN][MAXN];
    
    vector<pair<int,int> > elm[MAXN];
    int nxtx[MAXN],nxty[MAXN];
    
    queue<int> Qx,Qy;
    char bfsvis[MAXN][MAXN];
    const int dx[4]={0,1,0,-1};
    const int dy[4]={1,0,-1,0};
    int scc,val[MAXN];//10*10
    int bl[MAXN][MAXN],siz[MAXN];
    inline void bfs(const int &sx,const int &sy,const int &id){
     Qx.push(sx);Qy.push(sy);int st=num[sx][sy];
     while(!Qx.empty()){
      int u=Qx.front(),v=Qy.front();
      Qx.pop();Qy.pop();
      if(bfsvis[u][v])continue;
      elm[id].push_back(make_pair(u,v)); 
    //  cout<<"PUSH:"<<id<<" "<<u<<" "<<v<<endl;
      bl[u][v]=id;bfsvis[u][v]=1;
      siz[id]++;
      for(register int k=0;k<=3;k++){
       int x=u+dx[k],y=v+dy[k];
       if(x>n||y>n)continue;
       if(num[x][y]!=st)continue;
       if(bfsvis[x][y])continue;
       Qx.push(x);Qy.push(y);
      }
     }
    }
    int first_time;
    int ans[MAXN][MAXN],sav[MAXN][MAXN];
    
    int tmpval[MAXN];
    int ans_num;
    inline void check(){
     int flag=0;
     for(register int i=1;i<=n;i++){
      for(register int j=1;j<=n;j++){
       if(!flag){
        if(ans[i][j]>sav[i][j]){flag=2;break;}
        if(ans[i][j]<sav[i][j]){flag=1;break;}
       }
      }
     }
     ans_num++;
     if(flag==1) memcpy(sav,ans,sizeof(ans));
    }
    
    typedef long long ll;
    
    char occx[MAXN][MAXN],occy[MAXN][MAXN];
    ll sccmul[MAXN];
    int sccres[MAXN]; 
    
    
    inline ll qpow(ll x,ll y){
     ll ret=1ll;
     while(y){
      if(y&1)ret*=x;
      x*=x;
      y>>=1ll;
     }
     return ret;
    }
    
    void dfs(int dp){
     int x=nxtx[dp],y=nxty[dp];
     if(dp==n*n+1){
      if(!first_time){
       ans_num++;
       memcpy(sav,ans,sizeof(ans));
       first_time=1;
      }else check(); 
      return;
     }
     register int cur=bl[x][y],up=vaild[cur][0];
     if(sccmul[cur]>1ll*val[cur]){return;}
     if(1ll*sccmul[cur]*qpow(vaild[cur][up],siz[cur]-sccres[cur])<1ll*val[cur]){return;} 
     if(sccres[cur]==siz[cur]-1){
      int v=val[cur]/sccmul[cur];
      if(occx[x][v]||occy[y][v])return;
      occx[x][v]=1;occy[y][v]=1;
    //  sccres[cur]++;sccmul[cur]*=v;
      ans[x][y]=v;
      dfs(dp+1);
    //  sccres[cur]--;sccmul[cur]/=v;
      occx[x][v]=0;occy[y][v]=0;
     }else{ 
      for(register int i=1;i<=up;i++){
       int v=vaild[cur][i];
       if(occx[x][v]||occy[y][v])continue;
       ans[x][y]=v;
       occx[x][v]=1;occy[y][v]=1;
       sccres[cur]++;sccmul[cur]*=v;
       dfs(dp+1);
       sccres[cur]--;sccmul[cur]/=v;
       occx[x][v]=0;occy[y][v]=0;
      }
     }
    }
    
    int id[MAXN];
    inline bool cmp(const int &x,const int &y){
    // return siz[x]==siz[y]?val[x]<val[y]:siz[x]<siz[y]; 
     return val[x]==val[y]?siz[x]<siz[y]:val[x]<val[y];
    }
    
    int main(){
    // freopen("kenken.in","r",stdin);
    // freopen("kenken.out","w",stdout);
     n=rd();
     for(register int i=1;i<=n;i++){
      for(register int j=1;j<=n;j++){
       num[i][j]=rd();
      }
     }
     for(register int i=1;i<=n;i++){
      for(register int j=1;j<=n;j++){
       if(bfsvis[i][j])continue;
       bfs(i,j,++scc);val[scc]=num[i][j];
      }
     }
     int cc=0;
     for(register int i=1;i<=scc;i++){
      id[i]=i;
      for(register int j=1;j<=n;j++){
       if(val[i]%j)continue;
       vaild[i][++vaild[i][0]]=j;
      }
      sccmul[i]=1;
     }
     sort(id+1,id+1+scc,cmp);
     cc=0;
     for(int i=1;i<=scc;i++){
      int s=elm[id[i]].size();
      for(int j=0;j<s;j++){ 
       nxtx[++cc]=elm[id[i]][j].first;
       nxty[cc]=elm[id[i]][j].second;
      }
     }
    // for(int i=1;i<=cc;i++){
    //  cout<<nxtx[i]<<" "<<nxty[i]<<endl;
    // } 
     dfs(1);
     printf("%d
    ",ans_num);
     if(ans_num==0) return 0;
     for(register int i=1;i<=n;i++){
      for(register int j=1;j<=n;j++){
       printf("%d ",sav[i][j]);
      }
      putchar('
    ');
     }
     return 0;
    }
    View Code

    当然,还有神仙操作Dancing Links X,吊打搜索

    #include<bits/stdc++.h>
    using namespace std; 
    const int N=11,M=510;
    const int dx[4]={1,0,-1,0};
    const int dy[4]={0,1,0,-1};
    struct node2{ int c[N][N]; } ans[M];
    bool operator< (node2 x,node2 y){
        for(int i = 1; i < N; i++)
            for(int j = 1; j<N; j++)
                if(x.c[i][j] != y.c[i][j])
                    return x.c[i][j] < y.c[i][j];
        return 0;
    }
    struct node{ int x, y; };
    
    vector<node> b[N * N];
    vector<int> p[N * N]; 
    int a[N][N], c[N][N], h[N][N], h1[N][N], h2[N][N];
    int n, cnt = 0, tot = 0;
    
    int read() {
        int x = 0, f = 1;
        char c = 0;
        for (; !isdigit(c); c=getchar()) if(c == '-') f = -1;
        for (; isdigit(c); c=getchar()) x = x * 10 + c - 48;
        return x * f;
    }
    int factor(int x) {
        int t = 0;
        for (int i = 1; i * i <= x; i++)
            t += (int)(x % i == 0);
        return t;
    }
    bool cmp(vector<node> x, vector<node> y) {
        if (x.size() == y.size())
            return factor(x[0].x) <= factor(y[0].x);
        return x.size() < y.size();
    }
    void divide(int t, int x){
        for (int i = 1; i <= n; i++)
            if (x % i == 0) p[t].push_back(i);
    }
    void dfs(int x, int y) {
        h[x][y] = 1;
        b[cnt].push_back((node){ x, y });
        for (int i = 0; i < 4; i++) {
            int tx = x + dx[i];
            int ty = y + dy[i];
            if (tx > 0 && tx <= n && ty > 0 && 
                ty <= n && !h[tx][ty] &&
                a[tx][ty] == a[x][y])
                dfs(tx, ty);
        }
    }
    void work(int dep);
    void fillp(int t, int dep, int s, int tot) {
        if (dep > tot) work(t + 1);
        else {
            int x=b[t][dep].x, y = b[t][dep].y;
            for (int i = 0; i < p[t].size(); i++) {
                int u=p[t][i];
                if ((s == u || dep < tot) && s % u == 0 &&
                    !h1[x][u] && !h2[y][u]){
                    h1[x][u] = 1;
                    h2[y][u] = 1;
                    c[x][y] = u;
                    fillp(t, dep + 1, s / u, tot);
                    c[x][y] = 0;
                    h1[x][u] = 0;
                    h2[y][u]=0;
                }
            }
        }
    }
    void work(int dep) {
        if (dep > cnt) {
            tot++;
            for (int i = 1; i <= n; i++)
                for(int j = 1; j <= n; j++)
                    ans[tot].c[i][j] = c[i][j];
        } else {
            int num=b[dep][0].x;
            int tot=b[dep].size() - 1;
            fillp(dep, 1, num, tot);
        }
    }
    int main() {
    //    freopen("kenken.in", "r", stdin);
    //    freopen("kenken.out", "w", stdout); 
        n = read();
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                a[i][j] = read();
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                if (!h[i][j]) {
                    cnt++;
                    b[cnt].push_back((node){ a[i][j], 0 });
                    dfs(i, j);
                }
        sort(b + 1, b + cnt + 1, cmp);
        for (int i = 1; i <= cnt; i++)
            divide(i, b[i][0].x);
        work(1);
        cout << tot << "
    ";
        node2 t = ans[1];
        for (int i = 2; i <= tot; i++)
            t = min(t, ans[i]);
        for (int i = 1;i <= n; i++){
            for (int j = 1; j < n; j++)
                cout << t.c[i][j] << " ";
            cout << t.c[i][n] << "
    ";
        }
        return 0;
    }
    未经许可,禁止搬运。
  • 相关阅读:
    Windows10 安装 MySQL 并开启远程访问
    Navicat Premium 12 破解教程
    基于 debian9 安装 Windows10 双系统 丢失引导文件的修复办法
    SD从零开始59-61,跨公司的库存转移,Interface 修改,可用性检查和需求传递
    SD从零开始57-58,第三方订单处理,跨公司销售
    SD从零开始55-56, 风险管理, 付款卡
    SD从零开始51-54 信用控制范围, 信用范围数据维护, 自动信用控制, 信用控制-阻止后续功能
    SD从零开始47-50, 装运成本基础、控制、结算, 信用/风险管理概述
    SD从零开始45-46
    SD从零开始41-44
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9630149.html
Copyright © 2020-2023  润新知