zoukankan      html  css  js  c++  java
  • 模拟

    CODEVS1156作业调度方案

     题目描述 Description

    我们现在要利用m台机器加工n个工件,每个工件都有m道工序,每道工序都在不同的指定的机器上完成。每个工件的每道工序都有指定的加工时间。

    每个工件的每个工序称为一个操作,我们用记号j-k表示一个操作,其中j为1到n中的某个数字,为工件号;k为1到m中的某个数字,为工序号,例如2-4表示第2个工件第4道工序的这个操作。在本题中,我们还给定对于各操作的一个安排顺序。

    例如,当n=3,m=2时,“1-1,1-2,2-1,3-1,3-2,2-2”就是一个给定的安排顺序,即先安排第1个工件的第1个工序,再安排第1个工件的第2个工序,然后再安排第2个工件的第1个工序,等等。

    一方面,每个操作的安排都要满足以下的两个约束条件。

    (1) 对同一个工件,每道工序必须在它前面的工序完成后才能开始;

    (2) 同一时刻每一台机器至多只能加工一个工件。

    另一方面,在安排后面的操作时,不能改动前面已安排的操作的工作状态。

    由于同一工件都是按工序的顺序安排的,因此,只按原顺序给出工件号,仍可得到同样的安排顺序,于是,在输入数据中,我们将这个安排顺序简写为“1 1 2 3 3 2”。

    还要注意,“安排顺序”只要求按照给定的顺序安排每个操作。不一定是各机器上的实际操作顺序。在具体实施时,有可能排在后面的某个操作比前面的某个操作先完成。

    例如,取n=3,m=2,已知数据如下:

    则对于安排顺序“1 1 2 3 3 2”,下图中的两个实施方案都是正确的。但所需要的总时间分别是10与12。

    当一个操作插入到某台机器的某个空档时(机器上最后的尚未安排操作的部分也可以看作一个空档),可以靠前插入,也可以靠后或居中插入。为了使问题简单一些,我们约定:在保证约束条件(1)(2)的条件下,尽量靠前插入。并且,我们还约定,如果有多个空档可以插入,就在保证约束条件(1)(2)的条件下,插入到最前面的一个空档。于是,在这些约定下,上例中的方案一是正确的,而方案二是不正确的。

    显然,在这些约定下,对于给定的安排顺序,符合该安排顺序的实施方案是唯一的,请你计算出该方案完成全部任务所需的总时间。

    思路:模拟。读入数据后,简单的进行模拟。不过还是多交了好几遍,就是因为开小了数组范围。
    #include<iostream>
    #include<cstdio>
    using namespace std;
    int eng[21][21]={0},ti[21][21]={0},st[500]={0},last[21]={0},pre[21]={0};
    bool timm[21][10000]={false};
    int find(int x,int xx,int y)
    {
    int i,j;
    bool ff=false,fi=false;
    i=last[x];
    while (!ff)
    {
    fi=false;
    for (j=i;j<i+ti[x][xx];++j)
    {
    if (timm[y][j])
    {
    i=j;
    while (timm[y][i]) ++i;
    fi=true;
    break;
    }
    }
    if (!fi) ff=true;
    }
    return i;
    }
    int main()
    {
    int n,m,i,j,t,ans=0;
    cin>>m>>n;
    for (i=1;i<=n*m;++i)
      cin>>st[i];
    for (i=1;i<=n;++i)
      for (j=1;j<=m;++j)
        cin>>eng[i][j];
    for (i=1;i<=n;++i)
      for (j=1;j<=m;++j)
        cin>>ti[i][j];
    for (i=1;i<=n*m;++i)
    {
    ++pre[st[i]];
    t=find(st[i],pre[st[i]],eng[st[i]][pre[st[i]]]);
    for (j=t;j<t+ti[st[i]][pre[st[i]]];++j)
    timm[eng[st[i]][pre[st[i]]]][j]=true;
    last[st[i]]=t+ti[st[i]][pre[st[i]]];
    }
    for (i=1;i<=n;++i)
      ans=max(ans,last[i]);
    cout<<ans<<endl;
    } 
    View Code

    bzoj1033 ZJOI杀蚂蚁

    题目大意:根据给定题意模拟游戏过程。

    思路:相对比较清晰的大模拟。但因为第一次写这种大模拟,所以还是调试了很久。总结一下这次犯的很多错误:

            1)蚂蚁出生的时候不仅要满足场上不到6只蚂蚁的要求,还要满足(0,0)这个位置没有东西;

            2)在激光塔对拿蛋糕的目标攻击的时候,可能会攻击蚂蚁到线段距离<=0.5(直径为1,半径为0.5)的蚂蚁,这里的判断要十分注意。满足点在端点之间,并且点到直线的距离<=0.5;如果不是对拿蛋糕的目标攻击,就只需要攻击这一个就行了,别的都不符合(按线段式攻击也对,这样会快一些);

            3)在移动的时候,如果这个蚂蚁不能移动,就要把他的上一秒位置统一成这一秒的;

            4)蚂蚁死的时候,会改变队列的头,所以如果平移的这个蚂蚁是target的时候,也要相应的改变target。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define maxnode 200005
    #define inf 2100000000LL
    using namespace std;
    struct use{
        int old,rank,blood,x,y,ux,uy;
        bool antcake;
    }que[maxnode]={0};
    int d,r,n,m,s,head,tail,pao[25][2]={0},map[10][10][2]={0},dx[4]={0,1,0,-1},dy[4]={1,0,-1,0},target;
    bool cake=false,win=false;
    void burn()
    {
        que[++tail].old=1;que[tail].rank=(tail+5)/6;que[tail].blood=int(4*pow(1.1,que[tail].rank));
        que[tail].x=que[tail].y=0;que[tail].ux=que[tail].uy=-1;map[0][0][0]=1;que[tail].antcake=false;
    }
    void leavemessage()
    {
        int i,j;
        for (i=head;i<=tail;++i)
            map[que[i].x][que[i].y][1]+=(que[i].antcake ? 5 : 2);
    }
    bool canmove(int i,int xx,int yy)
    {
        if (xx<0||xx>n||yy<0||yy>m) return false;
        if (map[xx][yy][0]==1||(xx==que[i].ux&&yy==que[i].uy)) return false;
        return true;
    }
    void move()
    {
        int i,j,k,maxn,xx,yy;
        for (i=head;i<=tail;++i)
        {
            maxn=-1;
            for (k=0;k<=3;++k)
            {
                xx=que[i].x+dx[k];yy=que[i].y+dy[k];
                if (canmove(i,xx,yy)&&map[xx][yy][1]>maxn) maxn=map[xx][yy][1];
            }
            if (maxn>=0)
            {
                for (k=0;k<=3;++k)
                {
                    xx=que[i].x+dx[k];yy=que[i].y+dy[k];
                    if (canmove(i,xx,yy)&&map[xx][yy][1]==maxn) break;
                }
                if (que[i].old%5==0)
                {
                    k=(k==0?3:k-1);
                    while(1)
                    {
                        xx=que[i].x+dx[k];yy=que[i].y+dy[k];
                        if (canmove(i,xx,yy)) break;k=(k==0?3:k-1);
                    }
                }
                map[que[i].x][que[i].y][0]=0;map[xx][yy][0]=1;
                que[i].ux=que[i].x;que[i].uy=que[i].y;
                que[i].x=xx;que[i].y=yy;
            }
            else {que[i].ux=que[i].x;que[i].uy=que[i].y;}
            if (que[i].x==n&&que[i].y==m&&!cake)
            {
                cake=true;que[i].antcake=true;target=i;k=(int)(4*pow(1.1,que[i].rank));
                que[i].blood=min(k,que[i].blood+k/2);
            }
        }
    }
    //i炮塔 j蚂蚁 
    int fang(int i){return i*i;}
    int dis(int i,int j)
    {
        int x1,y1,x2,y2;
        x1=pao[i][0];y1=pao[i][1];x2=que[j].x;y2=que[j].y;
        return fang(x1-x2)+fang(y1-y2);
    }
    bool canattack(int i,int j)
    {
        if (dis(i,j)<=r) return true;
        else return false;
    }
    int disy(int i,int a,int b,int c){return fang(a*que[i].x+b*que[i].y+c);}
    void attackone(int i,int j,int kk)
    {
        int k,a,b,c,x1,y1,x2,y2;
        if (kk==1) que[j].blood-=d;
        else
        {
          x1=pao[i][0];y1=pao[i][1];x2=que[j].x;y2=que[j].y;
          a=y2-y1;b=x1-x2;c=y1*x2-y2*x1;
          for (k=head;k<=tail;++k)
            if (disy(k,a,b,c)*4<=fang(a)+fang(b)&&
               ((que[k].x>=x1&&que[k].x<=x2)||(que[k].x>=x2&&que[k].x<=x1))&&
               ((que[k].y>=y1&&que[k].y<=y2)||(que[k].y>=y2&&que[k].y<=y1))) 
                que[k].blood-=d;
        }
    }
    void die(int i)
    {
        int j;
        if (target==i){target=0;cake=false;}
        map[que[i].x][que[i].y][0]=0;++head;
        for (j=i;j>=head;--j) {que[j]=que[j-1];if (target==j-1) target=j;}
    }
    void attack()
    {
        int i,j,minn,mini;bool use[25]={false};
        if (target>0)
            for (i=1;i<=s;++i)
                if (canattack(i,target)) {attackone(i,target,0);use[i]=true;}
        for (i=1;i<=s;++i)
            if (!use[i])
            {
                minn=inf;mini=0;use[i]=true;
                for (j=head;j<=tail;++j)
                    if (canattack(i,j))
                        if (dis(i,j)<minn){minn=dis(i,j);mini=j;}
                if (mini>0) attackone(i,mini,1);
            }
        for (i=head;i<=tail;++i) 
          if (que[i].blood<0) die(i);
    }
    void after()
    {
        int i,j;
        for (i=head;i<=tail;++i)
            if (que[i].x==0&&que[i].y==0&&que[i].antcake) {win=true;return;}
        for (i=0;i<=n;++i)
          for (j=0;j<=m;++j)
            map[i][j][1]=max(0,map[i][j][1]-1);
        for (i=head;i<=tail;++i) ++que[i].old;
    }
    void work()
    {
        if (tail-head+1<6&&map[0][0][0]==0) burn();
        leavemessage();move();attack();after();
    }
    int main()
    {
        int i,j,t;
        scanf("%d%d%d%d%d",&n,&m,&s,&d,&r);r=r*r;
        for (i=1;i<=s;++i)
        {scanf("%d%d",&pao[i][0],&pao[i][1]);map[pao[i][0]][pao[i][1]][0]=1;}
        scanf("%d",&t);head=1;tail=0;target=0;
        for (i=1;i<=t;++i)
        {
            work();if (win) break;
        }
        if (win) printf("Game over after %d seconds
    ",i);
        else printf("The game is going on
    ");
        printf("%d
    ",tail-head+1);
        for (i=head;i<=tail;++i)
            printf("%d %d %d %d %d
    ",que[i].old-1,que[i].rank,que[i].blood,que[i].x,que[i].y);
    }
    View Code

    cogs284 内存分配

    题目大意:模拟内存的分配。给定内存的大小和一些请求(开始的时间、占用内存、占用时间),如果当前时间不能满足请求,就把它放进队列中(队首元素优先级最高),尽量往前放请求。输出完成所有请求的时间和放进队列的请求个数。

    思路:用链表模拟这个过程就可以了,用链表存下相连的空间;用优先队列维护正在用的请求,以便释放。在读入一个请求的时候,把优先队列里时间比当前时间小的全都释放空间,同时根据时间放入队列中的元素,但是要注意,优先队列中相同时间要都释放后在管队列里的请求。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define maxnode 10005
    using namespace std;
    struct Node{
        Node *ne;
        int ti,la;
        Node(int ti,int la):ti(ti),la(la) {ne=NULL;}
    }*root;
    struct use{
        int ten,st,en;
        bool operator < (const use &x)const
        {
            return ten>x.ten;
        }
    };
    int que[maxnode][2]={0},n;
    priority_queue<use> q;
    void release(use x)
    {
        Node *o,*q;
        o=root;
        while(o->ne != NULL)
        {
            if (o->ne->ti > x.en)
            {
                q=new Node(x.st,x.en);
                q->ne=o->ne;o->ne=q;
                while(q->ne!=NULL)
                {
                    if (q->la+1 == q->ne->ti&&q->ne->ti != n+1)
                    {
                        q->la=q->ne->la;q->ne=q->ne->ne;
                    }
                    else break;
                } q=o;
                if (q->la+1 == q->ne->ti&&q->ne->ti != n+1)
                {
                    q->la=q->ne->la;q->ne=q->ne->ne;
                }
                break;
            }
            o=o->ne;
        }
    }
    bool give(int m,int t,int i)
    {
        Node *o;int j;
        o=root;
        while(o->ne!=NULL)
        {
            if (o->ne->la - o->ne->ti + 1>=m)
            {
                j=o->ne->ti;
                o->ne->ti=o->ne->ti + m;
                if (o->ne->ti > o->ne->la) o->ne=o->ne->ne;
                q.push((use){i+t,j,j+m-1});
                return true;
            }
            else o=o->ne;
        }
        return false;
    }
    void print(Node *o)
    {
        if (o==NULL) return;
        printf("%d %d
    ",o->ti,o->la);print(o->ne);
    }
    int main()
    {
        freopen("memory.in","r",stdin);
        freopen("memory.out","w",stdout);
        
        int i,j,t,m,p,head,tail,ans=0,tt;use xx;
        bool f;
        scanf("%d",&n);head=1;tail=0;
        root=new Node(0,-1);root->ne=new Node(1,n);
        root->ne->ne=new Node(n+1,n);
        while(scanf("%d%d%d",&t,&m,&p)==3)
        {
            f=(t==0&&m==0&&p==0);
            while(!q.empty())
            {
                xx=q.top();
                if (xx.ten<=t||f)
                {
                    tt=xx.ten;
                    while(xx.ten==tt)
                    {
                        release(xx);q.pop();ans=max(ans,xx.ten);
                        if (q.empty()) break;
                        xx=q.top();
                    }
                    while (head<=tail&&give(que[head][0],que[head][1],tt)) ++head;
                }
                else break;
            }
            if (f) break;
            if (!give(m,p,t)) {que[++tail][0]=m;que[tail][1]=p;}
        }
        printf("%d
    %d
    ",ans,tail);
    }
    View Code
  • 相关阅读:
    常见的块级元素和行级元素
    CentOS 利用 yum 安装卸载软件常用命令
    MySQL 派生表(Derived Table) Merge Optimization
    MySQL中的两种临时表
    集中化管理平台 — Ansible 详解
    MySQL 错误码对照
    mysqldump 工具使用详解——参数选项
    git 命令参考手册
    XtraBackup 备份与恢复实例讲解
    XtraBackup 原理与安装
  • 原文地址:https://www.cnblogs.com/Rivendell/p/4644265.html
Copyright © 2011-2022 走看看