ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【JLU数据结构荣誉课】第二次上机实验

2021-05-16 17:35:39  阅读:256  来源: 互联网

标签:JLU 10 ch 上机 int 汉字 数据结构 rg include


->点我进原题
-> 7-1 数列查询
-> 7-2 稀疏矩阵之和
-> 7-3 文字编辑
-> 7-4 幸福指数

7-1 数列查询 (100 分)


代码长度限制 \(16 KB\)
时间限制 \(10 ms\)
内存限制 \(1 MB\)


Description

已知数列的通项公式为:

     f(n) = f(n-1)*11/10,f[1]=10. 

通项从左向右计算,* 和 / 分别表示整数乘法和除法。

现在,要多次查询数列项的值。

Input

第 \(1\) 行,1个整数 \(q\),表示查询的次数, \(1≤q≤10000\). 第 \(2\) 至 \(q+1\) 行,每行1个整数 \(i\),表示要查询 \(f(i)\) 的值。

Output

\(q\) 行,每行1个整数,表示 \(f(i)\) 的值。查询的值都在32位整数范围内。

Sample Input

3
1
2
3

Sample Output

10
11
12

思路

看这个时间和空间就是为了卡每查询一次递归一次的做法的,所以我们直接将 \(10^{5}\) 次的值求出存入 \(f\) 数组即可达到 \(O(n)\) 计算,\(O(1)\) 查询。

代码

#include<cstdio>
#include<cctype>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define rg register
#define ll long long
using namespace std;
inline int read(){
	rg int f = 0, x = 0;
	rg char ch = getchar();
	while(!isdigit(ch))	f |= (ch == '-'), ch = getchar();
	while( isdigit(ch))	x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
	return f? -x: x;
}
int f[100001];
int main(){
	int n = read();
	f[1] = 10;
	for(rg int i = 2; i <= 100000; ++i){
		f[i] = f[i - 1] * 11 / 10;
	}
	for(rg int i = 1; i <= n; ++i){
		int q = read();
		printf("%d\n", f[q]);
	}
	return 0;
}




7-2 稀疏矩阵之和 (100 分)


代码长度限制 \(16 KB\)
时间限制 \(100 ms\)
内存限制 \(10 MB\)


Description

矩阵 \(A\) 和 \(B\) 都是稀疏矩阵。请计算矩阵的和 \(A+B\).如果 \(A\)、\(B\) 不能做和,输出“Illegal!”

Input

矩阵的输入采用三元组表示,先 \(A\) 后 \(B\)。对每个矩阵:

第 \(1\) 行,3个整数 \(N\)、\(M\)、\(t\),用空格分隔,分别表示矩阵的行数、列数和非0数据项数,\(10≤N、M≤50000\),\(t≤min(N,M)\).

第 \(2\) 至 \(t+1\) 行,每行3个整数 \(r\)、\(c\)、\(v\),用空格分隔,表示矩阵 \(r\) 行 \(c\) 列的位置是非0数据项 \(v\), \(v\) 在32位有符号整型范围内。三元组默认按行列排序。

Output

矩阵 \(A+B\),采用三元组表示,默认按行列排序,非零项也在32位有符号整型范围内。

Sample Input

10 10 3
2 2 2
5 5 5
10 10 20
10 10 2
2 2 1
6 6 6

Sample Output

10 10 4
2 2 3
5 5 5
6 6 6
10 10 20

思路

纯模拟题。直接开大矩阵数组空间是不够的,所以要用三元组去存矩阵。要注意当两矩阵的长宽一样时才可以相加,其余都不合法;同时答案要用行列递增排序输出,所以要排一下序;最容易漏掉的一点是只输出非0结果的位置,所以例如 \(a [2] [2] = 1\)、\(b [2] [2] = -1\) 这种,相加后 \(c [2] [2] = 0\) 是不允许输出的。

代码

#include<cstdio>
#include<cctype>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#define rg register
#define ll long long
using namespace std;
inline int read(){
	rg int f = 0, x = 0;
	rg char ch = getchar();
	while(!isdigit(ch))	f |= (ch == '-'), ch = getchar();
	while( isdigit(ch))	x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
	return f? -x: x;
}
struct node{
	int x, y;
	int data;
}f[100001], g[100001], h[100001], ans[100001];
map<ll, int> mp, book;
inline bool cmp(node a, node b){
	if(a.x == b.x)	return a.y < b.y;
	return a.x < b.x;
}
int main(){
	int t1 = 0, t2 = 0;
	int tot = 0;
	int n = read(), m = read(), t = read();
	for(rg int i = 1; i <= t; ++i){
		f[++t1].x = read();
		f[t1].y = read();
		f[t1].data = read();
		mp[f[t1].x * 100000 + f[t1].y] += f[t1].data;
	}
	int r = read(), c = read(), v = read();
	if(n != r || m != c){
		printf("Illegal!\n");
		return 0;
	}
	for(rg int i = 1; i <= v; ++i){
		g[ ++t2].x = read();
		g[t2].y = read();
		g[t2].data = read();
		mp[g[t2].x * 100000 + g[t2].y] += g[t2].data;
	}
	for(rg int i = 1; i <= t; ++i){
		if(mp[f[i].x * 100000 + f[i].y] == 0)	continue;
		ans[++tot].x = f[i].x;
		ans[tot].y = f[i].y;
		ans[tot].data = mp[f[i].x * 100000 + f[i].y];
		book[f[i].x * 100000 + f[i].y] = 1;
	}
	for(rg int i = 1; i <= v; ++i){
		if(book[g[i].x * 100000 + g[i].y])	continue;
		if(mp[g[i].x * 100000 + g[i].y] == 0)	continue;
		ans[++tot].x = g[i].x;
		ans[tot].y = g[i].y;
		ans[tot].data = mp[g[i].x * 100000 + g[i].y];
	}
	printf("%d %d %d\n", n, m, tot);
	sort(ans + 1, ans + tot + 1, cmp);
	for(rg int i = 1; i <= tot; ++i){
		printf("%d %d %d\n", ans[i].x, ans[i].y, ans[i].data);
	}
	return 0;
}




7-3 文字编辑 (100 分)


代码长度限制 \(16 KB\)
时间限制 \(1000 ms\)
内存限制 \(2 MB\)


Description

一篇文章由 \(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\) 号汉字。

Input

第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\) 代表汉字的编号。

Output

若干行,每行1个整数,对应每个询问的结果汉字编号。

Sample Input

1
9999 4
B 1 2
A 3 9999
Q 1 1
Q 0 3

Sample Output

4
9998

思路

纯模拟题。类似约瑟夫问题,这次我们用链表来处理。记录一个 \(last\) 数组和一个 \(next\) 数组,先初始化为对应位置,再根据题目所述每一步修改、查询即可。

代码

#include<cstdio>
#include<cctype>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define rg register
#define ll long long
using namespace std;
inline int read(){
	rg int f = 0, x = 0;
	rg char ch = getchar();
	while(!isdigit(ch))	f |= (ch == '-'), ch = getchar();
	while( isdigit(ch))	x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
	return f? -x: x;
}
int main(){
	int t = read();
	while(t--){
		int n = read(), m = read();
		int next[100001], last[100001];
		for(rg int i = 1; i <= n; ++i)	next[i] = i + 1, last[i] = i - 1;
		next[n] = 1;
		last[1] = n;
		for(rg int i = 1; i <= m; ++i){
//			for(rg int i = 1; i <= n; ++i){
//				cout << last[i] << ' ' << next[i] << endl;
//			} 
			char ch[1];
			scanf("%s", ch);
//			cout << ch;
			int a = read(), b = read();
			if(ch[0] == 'A'){
				if(last[b] == a)	continue;
				next[last[a]] = next[a];
				last[next[a]] = last[a];
				last[a] = last[b];
				last[b] = a;
				next[last[a]] = a;
				next[a] = b;
			}
			if(ch[0] == 'B'){
				if(next[b] == a)	continue;
				next[last[a]] = next[a];
				last[next[a]] = last[a];
				next[a] = next[b];
				next[b] = a;
				last[next[a]] = a;
				last[a] = b;
			}
			if(ch[0] == 'Q'){
				if(a)	printf("%d\n", next[b]);
				if(!a)	printf("%d\n", last[b]);
			}
		}
	}
	return 0;
}
/*
1 
10 3
A 3 10
Q 1 1
Q 0 3
*/




7-4 幸福指数 (100 分)


代码长度限制 \(16 KB\)
时间限制 \(100 ms\)
内存限制 \(64 MB\)


Description

人生中哪段时间最幸福?幸福指数可能会帮你发现。幸福指数要求:对自己每天的生活赋予一个幸福值,幸福值越大表示越幸福。一段时间的幸福指数就是:这段时间的幸福值的和乘以这段时间的幸福值的最小值。幸福指数最大的那段时间,可能就是人生中最幸福的时光。

Input

第1行,1个整数 \(n\),\(1≤n≤100000\) ,表示要考察的天数。

第2行,\(n\) 个整数 \(Hi\),用空格分隔,\(Hi\) 表示第 \(i\) 天的幸福值,\(0≤Hi≤1000000\)。

Output

第1行,1个整数,表示最大幸福指数。

第2行,2个整数 \(l\) 和 \(r\),用空格分隔,表示最大幸福指数对应的区间 \([l,r]\) 。如果有多个这样的区间,输出最长最左区间。

Sample Input

7
6 4 5 1 4 5 6

Sample Output

60
1 3

思路

题目说所求最大幸福指数是一段区间的和乘以这段区间的最小值,而题目数据是 \(10^{6}\), 所以不能 \(O(n^{2})\) 的枚举端点,故使用单调栈。以每个点的值为最小值,向左向右找出以他为最小值的最长区间,正向维护一个递增的单调栈,查询当前第 \(i\) 个点左边第一个比它小的值存入 \(li\) ,再逆向维护一个递增的单调栈,查询当前第 \(i\) 个点右边第一个比它小的值存入 \(ri\),\(l+1\) 到 \(r-1\) 即为以每个点为最小值的最长区间,再进行 \(O(n)\) 扫描对最大值和区间特判进行更新即可。

代码

#include<cstdio>
#include<cctype>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#define rg register
#define ll long long
using namespace std;
inline int read(){
	rg int f = 0, x = 0;
	rg char ch = getchar();
	while(!isdigit(ch))	f |= (ch == '-'), ch = getchar();
	while( isdigit(ch))	x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
	return f? -x: x;
}
const int inf = 0x7fffffff;
int n;
ll sum[100001];
int l[100001], r[100001];
int stk[100001], top = 0;
int ml = 0, mr = 0;
ll maxn = -1;
inline int a(int n){
	return sum[n] - sum[n - 1];
}
signed main(){
	n = read(); 
	sum[0] = 0;
	for(rg int i = 1; i <= n; ++i){
		sum[i] = sum[i - 1] + read();
	}
	top = 0;
	stk[0] = 0;
	for(rg int i = 1; i <= n; ++i){
		while(top && a(stk[top]) >= a(i))	top --;
		l[i] = stk[top];
		stk[++ top] = i;
	}
	top = 0;
	stk[0] = n + 1;
	for(rg int i = n; i >= 1; --i){
		while(top && a(stk[top]) >= a(i))	top --;
		r[i] = stk[top];
		stk[++ top] = i;
	}
	for(rg int i = 1; i <= n; ++i){
		ll tmp = (sum[r[i] - 1] - sum[l[i]]) * a(i);
		if(maxn < tmp){
			maxn = tmp;
			ml = l[i] + 1;
			mr = r[i] - 1;
		} else if(maxn == tmp){
			if(mr - ml + 1 < ((r[i] - 1) - (l[i] + 1) + 1)){
				ml = l[i] + 1;
				mr = r[i] - 1;
			} else if(mr - ml + 1 == ((r[i] - 1) - (l[i] + 1) + 1)){
				if(ml > l[i] + 1){
					ml = l[i] + 1;
					mr = r[i] - 1;
				}
			}
		}
	}
	printf("%lld\n%d %d", maxn, ml, mr);
	return 0;
}

标签:JLU,10,ch,上机,int,汉字,数据结构,rg,include
来源: https://www.cnblogs.com/horrigue/p/14774080.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有