ACM ICPC 2013-2014. NEERC. Eastern Subregional Contest

ACM ICPC 2013-2014. NEERC. Eastern Subregional Contest

今天下午集训队打了这场比赛,做一下总结。

C题

题目描述

Cloners from the Kamino planet breed some of the finest clones. Such good results are due to the careful
management over the clones’ evolution. The Kaminuans are now busy working out a new study technology
that lets increase the clones’ effectiveness. The cloners have come up with a new control system CVS (Clone
Version System) that makes managing the progress of experiments easier. The system is quite simple to use.
The Kaminuans have some set of educational programs at their disposal. A clone’s effectiveness depends on
which programs and in which order he has learned. The Kaminuans can teach any clone a program as long
as this clone hasn’t learned it already.
To make the experiments even easier to conduct, the Kaminuans enabled canceling the changes made by the
last program the clone has learned. In this case, the clone’s knowledge returns to the level when the program
hasn’t yet been studied. Then this clone can study this program in the future. You can cancel programs at
any time unless the clone is at the basic knowledge level.
Besides the ‘roll back’ function, a clone can ‘re-learn’ a program. If one cancels some program by mistake,
he can cancel the cancellation. The CVS keeps record of each clone’s canceled programs. After a program is
canceled, the CVS adds another record. After a clone re-learn a program, the record is deleted. If a clone
learn (not relearn) a program, all cancellation record history of this clone is deleted. You can use the re-learn
function as long as the record history for this clone contains any records.
Finally, the system has a ‘clone’ option. If a Kaminuan likes the current variant of a clone, he can clone the
clone, that is, create a new clone with the same sequence of taught programs and cancellation history.
Initially the Kaminuans have a single clone with basic knowledge. Help them analyze the progress of the
experiments.

Sample Input

9 10
learn 1 5
learn 1 7
rollback 1
check 1
clone 1
relearn 2
check 2
rollback 1
check 1

Sample Output

5
7
basic

题意

一个机器人的克隆有5种操作

  • learn ci pi . 给ci学程序pi
  • rollback ci 撤销上次
  • relearn ci 重新学习撤销的程序
  • clone ci 将ci克隆
  • check ci 查询这个克隆的知识程度
    机器人的序号以出现的顺序标号,每个机器人的知识程度基础为basic
    给N次查询,对于每次check这个机器人的知识程度

解法

一道数据结构的模拟题,自己都没有想到能A掉,用到了一个很优雅的解法。一个机器人的学习和撤销可以生成一个学习树
这里写图片描述
显然撤销操作即是回溯到当前点的父亲节点。
最精髓的就是clone的实现,如果clone时直接将所有roolback的记录复制的话那么就会有浪费掉之前的记录。并且直接复制的时间复杂度为O(N),整体的复杂度为O(N^2),超时。

解决方案
  • 给连续的一段学习操作分配一个标号

这样每次学习就会分配一个新的序号,这样既对原本的克隆不会有影响,新的克隆也不会被以前的学习记录影响。克隆的时间复杂度就会降到O(1)。

#include<bits/stdc++.h>

using namespace std;

typedef vector<int> vec;
typedef vector<vec> vv;
typedef map<int,int>::iterator mit;
typedef pair<int,int> P;

const int SIZE = 500005;

struct node
{
    int know;
    int cancle;
    map<int,int> re;

}A[SIZE];

int no = 1;

int site[SIZE];
int clone = 1;
int inx[SIZE];
int inxn;

void learn(int n,int k)
{
    int fa = site[n];
    inx[n] = inxn++;
    //A[fa].ch.push_back(no++);
    no++;
    A[no-1].know = k;
    A[no-1].cancle = fa;
    site[n] = no - 1;
}

void roll(int n)
{
    int fa = site[n];
    site[n] = A[fa].cancle;
    A[site[n]].re[inx[n]] = fa;
    //printf("---- %d\n",A[site[n]].re[n]);
}

void cln(int n)
{
    clone++;
    site[clone] = site[n];
    inx[clone] = inx[n];
//    mit it = A[site[n]].re.find(n);
//    if(it != A[site[n]].re.end())
//        A[site[n]].re[clone] = A[site[n]].re[n];
}

void relearn(int n)
{
    int fa = site[n];
    int tno = A[fa].re[inx[n]];
    //printf("tno = %d\n",tno);
    site[n] = tno;
}

void check(int n)
{
    int fa = site[n];
    int res = A[fa].know;
    if(!res) printf("basic\n");
    else printf("%d\n",res);
}

int main()
{
    int N,M;
    A[0].know = 0;
    site[1] = 0;
    inx[1] = 1;
    inxn = 2;
    scanf("%d%d",&N,&M);
    while(N--)
    {
        char opt[10];
        int a,b;
        scanf("%s",opt);
        if(!strcmp(opt,"learn"))
        {
            scanf("%d%d",&a,&b);
            learn(a,b);
        }
        else if(!strcmp(opt,"rollback"))
        {
            scanf("%d",&a);
            roll(a);
        }
        else if(!strcmp(opt,"clone"))
        {
            scanf("%d",&a);
            cln(a);
        }
        else if(!strcmp(opt,"check"))
        {
            scanf("%d",&a);
            check(a);
        }
        else if(!strcmp(opt,"relearn"))
        {
            scanf("%d",&a);
            relearn(a);
        }
        //for(int i=1;i<=10;i++) printf("site[%d]=%d\n",i,site[i]);
    }


    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值