1 祖玛(Zuma)
分数 100
全屏浏览题目
切换布局
作者 upcdsa
单位 中国石油大学(华东)
祖玛是一款曾经风靡全球的游戏,其玩法是:在一条轨道上初始排列着若干个彩色珠子,其中任意三个相邻的珠子不会完全同色。此后,你可以发射珠子到轨道上并加入原有序列中。一旦有三个或更多同色的珠子变成相邻,它们就会立即消失。这类消除现象可能会连锁式发生,其间你将暂时不能发射珠子。
开发商最近准备为玩家写一个游戏过程的回放工具。他们已经在游戏内完成了过程记录的功能,而回放功能的实现则委托你来完成。
游戏过程的记录中,首先是轨道上初始的珠子序列,然后是玩家接下来所做的一系列操作。你的任务是,在各次操作之后及时计算出新的珠子序列。
输入格式:
第一行是一个由大写字母'A'~'Z'组成的字符串,表示轨道上初始的珠子序列,不同的字母表示不同的颜色。
第二行是一个数字n,表示整个回放过程共有n次操作。
接下来的n行依次对应于各次操作。每次操作由一个数字k和一个大写字母Σ描述,以空格分隔。其中,Σ为新珠子的颜色。若插入前共有m颗珠子,则k ∈ [0, m]表示新珠子嵌入之后(尚未发生消除之前)在轨道上的位序。
要求:
0 ≤ n ≤ 10^4
0 ≤ 初始珠子数量 ≤ 10^4
输出格式:
输出共n行,依次给出各次操作(及可能随即发生的消除现象)之后轨道上的珠子序列。
如果轨道上已没有珠子,则以“-”表示。
输入样例:
ACCBA
5
1 B
0 A
2 B
4 C
0 A
输出样例:
ABCCBA
AABCCBA
AABBCCBA
-
A
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
#include<bits/stdc++.h>
//载入万能头
using namespace std;
//定义了两个字符串数组、操作次数
char str1[10010];//能够容纳10的4次方
char str2[10010];//能够容纳10的4次方
int n;//能够容纳10的4次方
//这是一个操作的函数,对每次操作进行更新
void update(int k,char c)
{
char *p;
p = str1;//对原数据的临时存储
strcpy(str2, p+k);//将更新前的放入一条新字符串中
str1[k] = c;//按给定位置加入新增的单个字符—“颜色”
strcpy(str1+k+1, str2);//在新串后边加上原有的
}
//这个消除的函数
bool elimi()
{
int slen = strlen(str1);//对每次更新后的进行判断
int i = 0;//起始=0
while(i<slen)//逐个判断
{
char t = str1[i];
int star = i;
int time = 0;
while(i<slen&&t==str1[i])//如果相邻的相同
{
time++;//相同个数加一
i++;//接着下一个元素进行判断
}
if(time>=3)//符合三个相同——消去
{
strcpy(str2, str1+i);
strcpy(str1 + star, str2);
return true;
}
}
return false;//最后没有符合可以消去的了
}
int main()
{
int k;
char c;
scanf("%s", str1);//先输入初始串——"颜色"
scanf("%d", &n);//游戏操作次数
for(int i=0; i<n; i++)//进入逐个循环
{
scanf("%d %c", &k, &c);//输入第几个位置、加入的颜色
update(k, c);//进行数据更新
while(elimi());//更新后判断能不能消去
if(strlen(str1)==0)
{
printf("-\n");//如果是空串
}
else
{
printf("%s\n",str1);//更新后的结果
}
}
}
//本题的逻辑结构:
//采取的一般线性表/队列/栈/二叉树/图 等等
//本题的存储结构:顺序
//解题思路和算法:先对原串进行更新,更新后再判断是否能消去,若可以则消去(相当于再处理一次),得出最后结果
//效率:
//时间复杂度:O(n²)
//空间复杂度:S(n) = O(n)
//测试数据:(1)输入:
/*
ACCBA
5
1 B
0 A
2 B
4 C
0 A
*/
// (2)输出:
/*
ABCCBA
AABCCBA
AABBCCBA
-
A
*/
2 范围查询(Range)
分数 100
全屏浏览题目
切换布局
作者 upcdsa
单位 中国石油大学(华东)
数轴上有n个点,对于任一闭区间 [a, b],试计算落在其内的点数。
要求:
0 ≤ n, m ≤ 5×10^5
对于每次查询的区间[a, b],都有a ≤ b
各点的坐标互异,浮点数
输入格式:
第一行包括两个整数:点的总数n,查询的次数m。
第二行包含n个数,为各个点的坐标。
以下m行,各包含两个整数:查询区间的左、右边界a和b。
输出格式:
对每次查询,输出落在闭区间[a, b]内点的个数。
输入样例:
5 2
1 3 7 9 11
4 6
7 12
输出样例:
0
3
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
#include<bits/stdc++.h>
//载入万能头
using namespace std;
int main()
{
int n,m;//点的总数n,查询的次数m
int a,b,j,k;//查询区间的左、右边界a和b。以及符合查询区间的坐标
scanf("%d %d",&n,&m);//输入点的总数n,查询的次数m
float s[n+10];//建立浮点数组
for(int i=0;i<n;i++)
{
scanf("%f",&s[i]);//输入各个坐标点的值
}
for(int i=0;i<m;i++)
{
scanf("%d %d",&a,&b);//输入查询区间
int j=0;//小的边界值
int k=n-1;//大的边界值
for(;j<n;j++)
{
if(s[j] >= float(a))//符合最小区间的
{
break;
}
}
for(;k>=0;k--)
{
if(s[k] <= float(b))//符合最大区间的
{
break;
}
}
if(j>=k)//如果查询到的最小值坐标大于等于最大值的坐标——即符合区间的个数为零
{
printf("0\n");
}
else
{
printf("%d\n",k-j+1);//查询区间有符合的,则输出它们的个数
}
}
}
//本题的逻辑结构:队列
//本题的存储结构:顺序
//解题思路和算法:输入的顺序为升序序列,免去了排序的步骤,所以只需要从数组两端逐个对照就可以确定符合点的坐标,两者做差便可解
//效率:
//时间复杂度:O(n²)
//空间复杂度:S(n) = O(n)
//测试数据:(1)输入:
/*
5 2
1 3 7 9 11
4 6
7 12
*/
// (2)输出:
/*
0
3
*/
3 灯塔(LightHouse)
分数 100
全屏浏览题目
切换布局
作者 upcdsa
单位 中国石油大学(华东)
海上有许多灯塔,为过路船只照明。
(图一)
如图一所示,每个灯塔都配有一盏探照灯,照亮其东北、西南两个对顶的直角区域。探照灯的功率之大,足以覆盖任何距离。灯塔本身是如此之小,可以假定它们不会彼此遮挡。
(图二)
若灯塔A、B均在对方的照亮范围内,则称它们能够照亮彼此。比如在图二的实例中,蓝、红灯塔可照亮彼此,蓝、绿灯塔则不是,红、绿灯塔也不是。
现在,对于任何一组给定的灯塔,请计算出其中有多少对灯塔能够照亮彼此。
输入格式:
共n+1行。
第1行为1个整数n,表示灯塔的总数。
第2到n+1行每行包含2个整数x, y,分别表示各灯塔的横、纵坐标。
要求:
1 ≤ n ≤ 4×10^6
灯塔的坐标x, y是整数,且不同灯塔的x, y坐标均互异
1 ≤ x, y ≤ 10^8
输出格式:
1个整数,表示可照亮彼此的灯塔对的数量。
输入样例:
3
2 2
4 3
5 1
输出样例:
在这里给出相应的输出。例如:
1
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
#include<bits/stdc++.h>
//载入万能头
using namespace std;
int main()
{
int n;//定义一个整数
scanf("%d",&n);//输入灯塔的总数
int light[n+10][2];//定义一个二维数组,数组x参数代表灯塔的顺序,Y参数的“0”代表灯塔的x坐标、“1”代表灯塔的y坐标
for(int i=0;i<n;i++)
{
scanf("%d %d",&light[i][0],&light[i][1]);//先输入所有灯塔的坐标
}
int sum=0;//定义符合要求的灯塔对数,初始值为零
for(int i=0;i<n;i++)//从第一个灯塔开始查询
{
for(int j=i-1;j>=0;j--)//根据外循环来确定内循环的区间,这样可以避免前后出现重复的情况
{
if((light[i][0]-light[j][0])*(light[i][1]-light[j][1])>0)//任意两个点之间的x和y的差为同号,即相互照射到
{
sum++;//符合要求的两个灯塔便是一对,sum值+1
}
}
}
printf("%d\n",sum);//输出最终对数
return 0;
}
//本题的逻辑结构:数组(线性)
//本题的存储结构:顺序
/*解题思路和算法:根据题意,若两个灯塔A和B相互照亮,它们横坐标差(x1-x2)>0(即A在B的右边),那么A也必将在B的上边(纵坐标差也要>0),即(y1-y2)>0
如果它们横坐标差(x1-x2)<0(即A在B的左边),那么A将在B的下边(纵坐标差也要<0),即(y1-y2)<0
其他情况则不能找到
所以对于坐标差一定是同号的才能相互照亮到
*/
//效率:
//时间复杂度:O(n²)
//空间复杂度:S(n) = O(n²)
//测试数据:(1)输入:
/*
3
2 2
4 3
5 1
*/
// (2)输出:
/*
1
*/
4 列车调度(Train)
分数 100
全屏浏览题目
切换布局
作者 upcdsa
单位 中国石油大学(华东)
某列车调度站的铁道联接结构如Figure 1所示。
其中,A为入口,B为出口,S为中转盲端。所有铁道均为单轨单向式:列车行驶的方向只能是从A到S,再从S到B;另外,不允许超车。因为车厢可在S中驻留,所以它们从B端驶出的次序,可能与从A端驶入的次序不同。不过S的容量有限,同时驻留的车厢不得超过m节。
设某列车由编号依次为{1, 2, ..., n}的n节车厢组成。调度员希望知道,按照以上交通规则,这些车厢能否以{a1, a2, ..., an}的次序,重新排列后从B端驶出。如果可行,应该以怎样的次序操作?
输入格式:
共两行。
第一行为两个整数n,m。
第二行为以空格分隔的n个整数,保证为{1, 2, ..., n}的一个排列,表示待判断可行性的驶出序列{a1,a2,...,an}。
要求:
1 ≤ n ≤ 1,600,000
0 ≤ m ≤ 1,600,000
输出格式:
若驶出序列可行,则输出操作序列,其中push表示车厢从A进入S,pop表示车厢从S进入B,每个操作占一行。
若不可行,则输出No。
输入样例:
5 2
1 2 3 5 4
输出样例:
push
pop
push
pop
push
pop
push
push
pop
pop
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
#include<bits/stdc++.h>
//载入万能头
#define N 1600000+10
using namespace std;
int n,m;//定义总车厢数n和驻留的车厢数m
bool flag = 1;//判断序列的可行性(默认可行)
int a;//第二行逐个输入的序列号an
int top = -1;//队顶定的-1
int i = 1;//i为1,2,3,...,n
int k = 0;//定义数组下标
int Train[N],op[2*N];//定义栈和标记操作的数组
void Judge()
{
if(top!=-1&&Train[top]==a)
{
//若栈非空且栈顶元素为t
top--;//出栈
k++;
}
else
{
flag=0;
}
}
int main()
{
scanf("%d %d",&n,&m);//输入第一行数据
for(int t=0; t<n; t++) //进入循环开始输入
{
if(flag==0)//每次输入前先判断之前的序列是否可行,如果不行的话直接退出
{
break;
}
else//可行的时候接着输入
{
scanf("%d",&a);//输入an
if(i<=a)//说明a未入栈,需要入栈
{
for(; top<m-1 && i<=a; i++) //(顺序上前边的还没入)将i到a入栈,top是从-1开始的,所以top应该 < m-1
{
Train[++top] = i;//开始入栈
op[k++] = 1;// 规定1为push,0为pop
}
Judge();
}
else
{
Judge();
}
}
}
if(flag==0)
{
printf("No\n");
}
else
{
for(i=0; i<k; i++)
{
if(op[i]==1)
{
printf("push\n");
}
else
{
printf("pop\n");
}
}
}
return 0;
}
//本题的逻辑结构:栈
//本题的存储结构:顺序储存
/*解题思路和算法:根据题意,使用一维数组和int类型的指针模拟栈的基本操作,
再设另一变量i作为入栈序列1,2,...n中的任意一个并不断自增,若i不大于出栈序
列out中的元素t,则入栈并判定栈是否空(m=0的情况),若空则out不可行。
若i>t,则若判定栈非空且栈顶元素为t,出栈,反之out不可行。再定义一个一维
数组,元素为0为pop,1为push,时刻“记录”每次出栈或入栈的操作,最后根据
可行标志输出。
*/
//效率:
//时间复杂度:O(n²)
//空间复杂度:S(n) = O(n)
//测试数据:(1)输入:
/*
5 2
1 2 3 5 4
*/
// (2)输出:
/*
push
pop
push
pop
push
pop
push
push
pop
pop
*/