您的位置:首页 > 其它

ACM ICPC 2013-2014. NEERC. Eastern Subregional Contest

2015-08-16 01:13 671 查看

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
;
inx
= inxn++;
//A[fa].ch.push_back(no++);
no++;
A[no-1].know = k;
A[no-1].cancle = fa;
site
= no - 1;
}

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

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

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

void check(int n)
{
int fa = site
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: