区间最小值I
分数 100
作者 谷方明
单位 吉林大学
对N个整数的序列,从左到右连续查询 M 长度子序列 A
i
,A
i+1
,...,A
i−M+1
(1≤i,M≤N)的最小值。
输入格式:
第1行,两个整数:N和M,表示整数的个数和区间长度,1≤N≤100000.
第2行,N个整数,每个整数x 都满足 │x│≤2000000000。
输出格式:
1行, 用空格分隔的N-M+1个整数,对应从左到右所有连续M长度子序列的最小值。
输入样例:
6 3
1 2 5 3 4 6
输出样例:
1 2 3 3
#include <stdio.h>
long long x[100000][2];
int main(void)
{
long long n, m, a, b, c = 0, d = 0, i;
scanf("%lld %lld", &n, &m);
for (a = 0; a < n; a++)
{
scanf("%lld", &i);
for (b = c; b >= 0; b--) //单调性维护
{
if (b == d || i > x[b - 1][0])
{
x[b][0] = i;
x[b][1] = a;
c++;
break;
}
else
{
x[b - 1][0] = 0;
x[b - 1][1] = 0;
c--;
}
}
if (x[c - 1][1] - x[d][1] >= m) //区间维护
{
x[d][1] = 0;
x[d][0] = 0;
d++;
}
if (a + 1 >= m)
{
if(n-a!=1)
printf("%lld ", x[d][0]);
else
printf("%lld", x[d][0]);
}
}
}
森林的层次遍历
分数 100
作者 谷方明
单位 吉林大学
给定一个森林F,求F的层次遍历序列。森林由其先根序列及序列中每个结点的度给出。
输入格式:
第1行,1个整数n,表示森林的结点个数, 1≤n≤100000.
第2行,n个字符,用空格分隔,表示森林F的先根序列。字符为大小写字母及数字。
第3行,n个整数,用空格分隔,表示森林F的先根序列中每个结点对应的度。
输出格式:
1行,n个字符,用空格分隔,表示森林F的层次遍历序列。
输入样例:
在这里给出一组输入。例如:
14
A B C D E F G H I J K L M N
4 0 3 0 0 0 0 2 2 0 0 0 1 0
输出样例:
在这里给出相应的输出。例如:
A M B C G H N D E F I L J K
#include <stdio.h>
#include<malloc.h>
#include<string.h>
int x[100100][2];
char y[100100][10];
int z[100100];
int t[100100];
int main()
{
int n, a, b=1, c, d=0;
char ch;
scanf("%d", &n);
for (a = 0; a < n; a++)
{
scanf("%s", y[a]);
}
for (a = 0; a < n; a++)
{
scanf("%d", &z[a]);
}
for (a = 0; a < n; a++)
{
x[b][0] = a;
x[b][1] = z[a];
t[a] = b;
x[b - 1][1]--;
for (; x[b][1] == 0;)
{
b--;
}
b++;
}
for (a = 1; a < 100; a++)
{
for (b = 0; b < n; b++)
{
if (t[b] == a)
{
if (d == 0)
{
printf("%s", y[b]);
d = 1;
}
else
printf(" %s", y[b]);
}
}
}
return 0;
}
数列查询
分数 100
作者 谷方明
单位 吉林大学
已知数列的通项公式为:
f(n) = f(n-1)*11/10,f[1]=10.
通项从左向右计算,*和/分别表示整数乘法和除法。
现在,要多次查询数列项的值。
输入格式:
第1行,1个整数q,表示查询的次数, 1≤q≤10000.
第2至q+1行,每行1个整数i,表示要查询f(i)的值。
输出格式:
q行,每行1个整数,表示f(i)的值。查询的值都在32位整数范围内。
输入样例:
在这里给出一组输入。例如:
3
1
2
3
输出样例:
在这里给出相应的输出。例如:
10
11
12
#include <stdio.h>
int x[10000100];
int y[10010];
int main()
{
int n, a,i=0;
x[1]=10;
scanf("%d", &n);
for (a = 0; a < n; a++)
{
scanf("%d", &y[a]);
if (y[a] > i)
i = y[a];
}
for (a = 1; a <= i; a++)
{
x[a + 1] = x[a] * 11 / 10;
}
for (a = 0; a < n-1; a++)
{
printf("%d\n", x[y[a]]);
}
printf("%d", x[y[a]]);
return 0;
}
一篇文章由n个汉字构成,汉字从前到后依次编号为1,2,……,n。
有四种操作:
A i j表示把编号为i的汉字移动编号为j的汉字之前;
B i j表示把编号为i的汉字移动编号为j的汉字之后;
Q 0 i为询问编号为i的汉字之前的汉字的编号;
Q 1 i为询问编号为i的汉字之后的汉字的编号。
规定:1号汉字之前是n号汉字,n号汉字之后是1号汉字。
输入格式:
第1行,1个整数T,表示有T组测试数据, 1≤T≤9999.
随后的每一组测试数据中,第1行两个整数n和m,用空格分隔,分别代表汉字数和操作数,2≤n≤9999,1≤m≤9999;第2至m+1行,每行包含3个常量s、i和j,用空格分隔,s代表操作的类型,若s为A或B,则i和j表示汉字的编号,若s为Q,i代表0或1,j代表汉字的编号。
输出格式:
若干行,每行1个整数,对应每个询问的结果汉字编号。
输入样例:
在这里给出一组输入。例如:
1
9999 4
B 1 2
A 3 9999
Q 1 1
Q 0 3
输出样例:
在这里给出相应的输出。例如:
4
9998
#include<string.h>
#include<stdio.h>
#include <malloc.h>
struct cell
{
int date;
struct cell* next;
};
struct cell* head;
void fi(int b, int c)
{
int a;
struct cell* p,*p0;
p0 = head;
p = (struct cell*)malloc(sizeof(struct cell));
p->date = c;
for (a = 1; a < b; a++)
{
if (p0 == NULL)
return;
p0 = p0->next;
}
if (p0 == NULL)
return;
p->next = p0->next;
p0->next = p;
}
void fe(int b)
{
int a;
struct cell* p=head,*p0;
for (a = 1; a < b; a++)
{
if (p == NULL)
return;
p = p->next;
}
if (p->next == NULL||p==NULL)
return;
p0 = p->next->next;
p->next =p0;
}
void fu(int b,int c)
{
int a;
struct cell* p = head;
for (a = 0; a < b; a++)
{
if (p == NULL)
return;
p = p->next;
}
if (p == NULL)
return;
p->date = c;
}
int fq(int b)
{
int a;
struct cell* p = head;
for (a = 0; a < b; a++)
{
if (p == NULL)
return -1;
p = p->next;
}
if (p == NULL)
return -1;
return p->date;
}
int main()
{
head = (struct cell*)malloc(sizeof(struct cell));
head->next = NULL;
head->date = -1;
int n, a, b, c,d;
char ch;
scanf("%d", &n);
for (a = 0; a < n; a++)
{
scanf("%c", &ch);
while (ch != 'I' && ch != 'E' && ch != 'U' && ch != 'Q')
scanf("%c", &ch);
if (ch == 'I')
{
scanf("%d %d", &b, &c);
fi(b, c);
}
if (ch == 'E')
{
scanf("%d",&b);
fe(b);
}
if (ch == 'U')
{
scanf("%d %d", &b, &c);
fu(b, c);
}
if (ch == 'Q')
{
scanf("%d", &b);
printf("%d\n",fq(b));
}
}
return 0;
}