zoukankan      html  css  js  c++  java
  • 提高组刷题班 DAY 1 上午

    低仿机器人
    (robo,1s,64M)

     

     题解

    大模拟

     代码

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    const int xGo[4]={-1,0,1,0};
    const int yGo[4]={0,-1,0,1};
    
    int n,m,map[220][220][2];
    int x,y,fOri,wOri,maxCilp,totCilp,cilp[32],bigBullet,smallBullet,k,endIf,totTarget;
    
    void IN_Map_Robot();
    void OutPut(int);
    int Para(char str[]);
    
    void FortCom(char str[]);
    void WheelCom(char str[]);
    void EndCom(char str[]);
    
    int main()
    {
        freopen("robo.in","r",stdin);
        freopen("robo.out","w",stdout);
        int t;
        scanf("%d",&t);
        while(t--)
        {
            IN_Map_Robot();
            while(k--)
            {
                char str[10];
                cin.getline(str,10);
                if(endIf) continue;
                if(str[0]=='F') FortCom(str);
                if(str[0]=='W') WheelCom(str);
                if(str[0]=='E') EndCom(str);
            }
            if(!endIf) OutPut(0);
        }
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    
    void IN_Map_Robot()
    {
        memset(map,0,sizeof(map));
        totCilp=0,fOri=0,wOri=0,endIf=0,totTarget=0;
    
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;++i)
            for(int j=0;j<m;++j)
                scanf("%d ",&map[i][j][0]);
        scanf("%d %d %d %d %d %d
    ",&x,&y,&maxCilp,&bigBullet,&smallBullet,&k);
    }
    
    void FortCom(char str[])
    {
        if(str[1]=='T')
        {
            int par=Para(str+3);
            if(par==0) fOri=(fOri+1)%4;
            else if(par==1) fOri=(fOri+3)%4;
            else { OutPut(0); return ; }
        }
        if(str[1]=='F')
        {
            int par=Para(str+3);
            if((par==0&&smallBullet==0)||(par==1&&bigBullet==0)) return;
            if(par==0&&totCilp<maxCilp) cilp[++totCilp]=par,smallBullet--;
            else if(par==1&&totCilp<maxCilp) cilp[++totCilp]=par,bigBullet--;
            else { OutPut(0); return ; }
        }
        if(str[1]=='E')
        {
            if(totCilp==0) return ;
            int nx,ny;
            for(int i=1;;++i)
            {
                nx=x+xGo[fOri]*i,ny=y+yGo[fOri]*i;
                if(nx<0||nx>=n||ny<0||ny>=m) break;
                if(map[nx][ny][0]==1||map[nx][ny][0]==2) break;
            }
            totCilp--;
            if(nx<0||nx>=n||ny<0||ny>=m) return ;
            if(map[nx][ny][0]==1) return ;
            if(cilp[totCilp+1]||map[nx][ny][1]) { map[nx][ny][0]=0; totTarget++; }
            else map[nx][ny][1]=1;
        }
    }
    
    void WheelCom(char str[])
    {
        if(str[1]=='T')
        {
            int par=Para(str+3);
            if(par==0) wOri=(wOri+1)%4;
            else if(par==1) wOri=(wOri+3)%4;
            else { OutPut(0); return ; }
        }
        else
        {
            int par=Para(str+3);
            int nx=x+xGo[wOri]*par,ny=y+yGo[wOri]*par;
            if(nx<0||nx>=n||ny<0||ny>=m) { OutPut(0); return ; }
            else
            {
                for(int i=1;i<=par;++i)
                {
                    nx=x+xGo[wOri]*i,ny=y+yGo[wOri]*i;
                    if(map[nx][ny][0]) { OutPut(0); return ; }
                }
            }
            x=nx,y=ny;
        }
    }
    
    void EndCom(char str[])
    {
        OutPut(1);
    }
    
    void OutPut(int type)
    {
        endIf=1;
        if(type) printf("Complete
    ");
        else printf("ERROR
    ");
        printf("%d %d
    ",x,y);
        printf("%d
    ",totTarget);
        printf("%d %d %d %d
    ",fOri,wOri,bigBullet,smallBullet);
    }
    
    int Para(char str[])
    {
        int i,re=0;
        for(i=0;;++i)
        {
            if(str[i]=='.') return 114514;
            if(str[i]=='') break;
        }
        i=0;
        do
        {
            re=re*10+(str[i]-'0');
            i++;
        }while(str[i]!='');
        return re;
    }

     迷路的刺豚

     

     

     

     

     

    DFS  搜出,路径,同样长度但是膨胀程度不一样 

    状压DP+BFS

    f[s][i]------(+dis[i][j])------->f[s|(1<<j)][j] 

     

     代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N=505,M=505,K=15;
    const int dx[4]={0,0,1,-1};
    const int dy[4]={1,-1,0,0};
    const char* st[4]={"R","L","D","U"};
    
    int Path[(N+M)<<1],n,m,S;
    int mp[N][M];
    
    void Read_Map() {
        scanf("%d%d%d",&n,&m,&S);
        for (int i=0;i<n;++i) 
            for (int j=0;j<m;++j) scanf("%d",&mp[i][j]);//mp=0为可行,否则为障碍 
    }
    
    queue<pair<int,int> >Q;
    int Path_[K+1][K+1][(N+M)<<1],dist[K+1][K+1],szt[K+1][K+1];
    int dis[K][1<<K],sum[K][1<<K];
    pair<int,int> pre[K][1<<K];
    
    
    void Put_Path(int *Path,int &len,int begin,int end) {
        for (int i=0;i<dist[begin][end];++i)
            Path[len++]=Path_[begin][end][i];
    }
    
    bool CoordValid(int x,int y) {
        return x>=0 && x<n && y>=0 && y<m;
    }
    
    bool CoordValid(int x,int y,int size) {
        for (int i=-size;i<=size;++i)
            for (int j=-size;j<=size;++j)
                if (!CoordValid(x+i,y+j) || mp[x+i][y+j]==1) return 0;
        return 1;
    }
    
    int Size(int x,int y) {
        for (int i=S;i>=0;--i) if (CoordValid(x,y,i)) return i; 
        return -1;
    }
    
    int pree[N][M],diss[N][M],sz[N][M];
    void FindPath(int *ax,int *ay,int count) {
        for (int i=0;i<count;++i) {
             Q.push(make_pair(ax[i],ay[i]));
            memset(pree,0,sizeof(pree));
            memset(diss,0x7f,sizeof(diss));
            memset(sz,0,sizeof(sz));
            diss[ax[i]][ay[i]]=0;
            while (!Q.empty()) {
                pair<int,int> u=Q.front(); Q.pop();
                for (int i=0;i<4;++i) {
                    int tx=u.first+dx[i],ty=u.second+dy[i],s=Size(tx,ty);
                    if (s!=-1 && (diss[tx][ty]>diss[u.first][u.second]+1 || (diss[tx][ty]==diss[u.first][u.second]+1 && sz[u.first][u.second]+s>sz[tx][ty]))) {
                        diss[tx][ty]=diss[u.first][u.second]+1;
                        pree[tx][ty]=i;
                        sz[tx][ty]=sz[u.first][u.second]+s;
                        Q.push(make_pair(tx,ty));
                    }
                }
            }
            for (int j=0;j<count;++j) {
                dist[i][j]=diss[ax[j]][ay[j]];
                szt[i][j]=sz[ax[j]][ay[j]];
    //            int len=0,nowx=ax[j],nowy=ay[j];
    //            while (nowx!=ax[i] || nowy!=ay[i]) {
    //                Path_[i][j][len++]=pree[nowx][nowy];
    //                int px=nowx-dx[pree[nowx][nowy]],py=nowy-dy[pree[nowx][nowy]];
    //                nowx=px; nowy=py;
    //            }
    //            reverse(Path_[i][j],Path_[i][j]+len);
            }
        }
    }
    
    void Planning(int now_x,int now_y,int *aim_x,int *aim_y,int count_aim,int *Path,int &len) {
        aim_x[count_aim]=now_x; aim_y[count_aim]=now_y;
        FindPath(aim_x,aim_y,count_aim+1);
        int Mx=1<<count_aim;
        for (int i=0;i<=count_aim;++i)
            for (int j=0;j<Mx;++j)
                pre[i][j]=make_pair(-1,-1),dis[i][j]=1<<30;
        for (int i=0;i<count_aim;++i) dis[i][(Mx-1)^(1<<i)]=0,sum[i][(Mx-1)^(1<<i)]=0;
        for (int i=0;i<count_aim;++i)
            for (int j=Mx-1;j>=0;--j)
                for (int k=0;k<count_aim;++k) if (i!=k && !((j>>k)&1) && (dis[i][j]>dis[k][j^(1<<i)]+dist[i][k] || ( dis[i][j]==dis[k][j^(1<<i)]+dist[i][k] && sum[i][j]<sum[k][j^(1<<i)]+szt[i][k] ) )) {
                    dis[i][j]=dis[k][j^(1<<i)]+dist[i][k];
                    sum[i][j]=sum[k][j^(1<<i)]+szt[i][k];
                    pre[i][j]=make_pair(k,j^(1<<i)); 
                } 
    
        int mn=0,v=0; len=0;
        for (int i=1;i<count_aim;++i) if (dis[i][v]+dist[count_aim][i]<dis[mn][v]+dist[count_aim][mn] || (dis[i][v]+dist[count_aim][i]==dis[mn][v]+dist[count_aim][mn] && sum[i][v]+szt[count_aim][i]>sum[mn][v]+szt[count_aim][mn])) mn=i;
        printf("%d %d
    ",dis[mn][v]+dist[count_aim][mn],sum[mn][v]+Size(now_x,now_y)+szt[count_aim][mn]);
    /*
        for (int i=1;i<count_aim;++i) if (dis[i][v]+dist[count_aim][i]<dis[mn][v]+dist[count_aim][mn]) mn=i;
        Put_Path(Path,len,count_aim,mn);
        while (pre[mn][v].first!=-1) {
            pair<int,int> u=pre[mn][v];
            Put_Path(Path,len,mn,u.first);
            mn=u.first; v=u.second;
        }
    */ 
    }
    
    int main() {
        freopen("expand.in","r",stdin);
        freopen("expand.out","w",stdout);
        Read_Map();
        int now_x,now_y,aim_x[K],aim_y[K],count_aim;
        scanf("%d%d%d",&now_x,&now_y,&count_aim);
        for (int i=0;i<count_aim;++i) scanf("%d%d",&aim_x[i],&aim_y[i]);
        int len=0;
        Planning(now_x,now_y,aim_x,aim_y,count_aim,Path,len);
    //    for (int i=0;i<len;++i) 
    //        printf("%s",st[Path[i]]);
        putchar('
    ');
        fclose(stdin);
        fclose(stdout);
        return 0; 
    } 
    
    /*
    input: 
    4 6 3
    1 1 1 0 0 0 
    0 0 0 0 0 0 
    0 0 0 0 0 0 
    0 0 0 0 0 0 
    0 4 1
    3 0 
    
    output:
    7 5
    */

    生日(birthday.cpp/1s/256M)

    样例输入:

    20 20 152
    3 26 133 54 79 81 72 109 66 91 82 100 35 23 104 17 51 114 12 58
    2 1 17
    2 6 12
    1 1 12
    2 3 5
    2 11 11
    2 7 19
    2 6 15
    1 5 12
    1 1 9
    1 10 19
    2 3 19
    2 6 20
    2 1 13
    2 1 15
    2 1 9
    1 1 1
    2 1 7
    2 7 19
    2 6 19
    2 3 6

    样例输出

    Yes
    Yes
    Yes
    Yes
    No

     题解

     

     (图右半边是折半搜索)

     解释一哈:

    因为区间内的每个小盆友都可以有选或者不选两种情况,所以一共有2len

    所以该区间的子集种类数:有2len 种

    子集和的范围:0~v*len

    2len 种子集本应该是与v*len一一映射的

    但是当2len > v*len 时,

     集合的取值一定会有重复的,所以此时一定有解

    解得 len>=14

    ∴len<14时要折半搜索

     因为之前处理过 len<=7 的情况

    那么有重复的怎么办???

    其实不影响

    比如序列     1   1   3   2

    所选集合有重叠,但是他们相等,那么去掉重复的之后也是相等的

    代码

    # include <iostream>
    # include <cstdio>
    # include <cstring>
    # include <cstdlib>
    using namespace std;
    const int V = 1e3 + 10;
    const int N = 1e5 + 12;
    int read()
    {
        int ans = 0,f = 1;
        char i = getchar();
        while(i < '0' || i > '9'){if(i == '-')f = -1;i = getchar();}
        while(i >= '0' && i <= '9'){ans = ans * 10 + i - '0';i = getchar();}
        return ans * f;
    }
    int n,m,v,mid,ol,x,y,d;
    int data[V][22],a[N],stack[N],cnt;
    int sum[N << 2],lazy[N << 2];
    bool flag[N];
    void down(int rt){
        lazy[rt << 1] += lazy[rt];
        lazy[rt << 1 | 1] += lazy[rt];
        lazy[rt] = 0;
    }
    void push(int &ans,int &r){
        int j = 20;
        while(j >= 0){
            if(r >= (1 << j)){
               ans = data[ans][j];
               r -= (1 << j);
               if(r == 0)return;
            }
            j--;
        }
    }
    void updata(int L,int R,int l,int r,int rt){
        if(L <= l && r <= R){
            lazy[rt]++;
            return;
        }
        if(lazy[rt])down(rt);
        int mid = (l + r) >> 1;
        if(L <= mid)updata(L,R,l,mid,rt << 1);
        if(R >  mid)updata(L,R,mid + 1,r,rt << 1 | 1);
        return;
    }
    void Query(int L,int l,int r,int rt){
        if(l == r){
            push(a[L],lazy[rt]);
            return;
        }
        if(lazy[rt])down(rt);
        int mid = (l + r) >> 1;
        if(L <= mid)Query(L,l,mid,rt << 1);
        else Query(L,mid + 1,r,rt << 1 | 1);
        return;
    }
    void init(){
        for(int i = 0;i < v;i++){
            data[i][0] = (i * i % v) * i % v;
        }
        for(int j = 1;j <= 20;j++){
            for(int i = 0;i < v;i++){
               data[i][j] = data[data[i][j - 1]][j - 1];
            }    
        }
    }
    void dfsl(int u,int dis,bool k){
        if(ol)return;
        if(u == mid + 1){
            if(k){
                if(!dis){
                    ol = true;
                }else if(dis >= 0 && !flag[dis]){flag[dis] = true;stack[++cnt] = dis;}
            }
            return;
        }
        dfsl(u + 1,dis,k);
        dfsl(u + 1,dis + a[u] + 1,true);
        dfsl(u + 1,dis - a[u] - 1,true);
        return;
    }
    void dfsr(int u,int dis,bool k){
        if(ol)return;
        if(u == y + 1){
            if(k){
                if(!dis){
                    ol = true;
                }else if(dis >= 0 && flag[dis]){
                    ol = true;
                }
            }
            return;
        }
        dfsr(u + 1,dis,k);
        dfsr(u + 1,dis + a[u] + 1,true);
        dfsr(u + 1,dis - a[u] - 1,true);
        return;
    }
    int main(){
         freopen("birthday.in","r",stdin);
         freopen("birthday.out","w",stdout);
      n = read(),m = read(),v = read();
      for(int i = 1;i <= n;i++)a[i] = read();
      init();
      for(int i = 1;i <= m;i++){
          d = read(),x = read(),y = read();
          if(d == 2){
              updata(x,y,1,n,1);
          }else {
              if(y - x >= 13){
                  puts("Yes");
              }else {
                for(int j = x;j <= y;j++){
                    Query(j,1,n,1);
                }
                mid = (x + y) >> 1;
                ol = false;cnt = 0;
                dfsl(x,0,false);
                dfsr(mid + 1,0,false);
                for(int i = 1;i <= cnt;i++){
                    flag[stack[i]] = false;
                }
                if(ol)puts("Yes");else puts("No");
             }
          }
      }
      fclose(stdin);
      fclose(stdout);
      return 0;
    }
  • 相关阅读:
    正则表达式预:
    cookie 二:
    Javascript之运动框架2
    cookie预:
    Javascript之链式运动框架1
    基于Azure的软件部署和开发系列沙龙
    在Docker中安装.NET Core(使用命令行工具)
    Xshell 无法连接虚拟机中的ubuntu的问题
    springboot09-redis
    springboot08-jpa-mysql
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11615475.html
Copyright © 2011-2022 走看看