CSU 1515: Sequence
来源:互联网 发布:软件设计师 考试 编辑:程序博客网 时间:2024/05/23 19:23
题目:
Description
Give you a sequence consisted of n numbers. You are required to answer how many pairs of numbers (ai, aj) satisfy that | ai - aj | = 1 and L ≤ i < j ≤ R.
Input
The input consists of one or more test cases.
For each case, the first line contains two numbers n and m, which represent the length of the number sequence and the number of queries. ( 1 ≤ n ≤ 10^4, 1 ≤ m ≤ 10^5 )
The second line consists of n numbers separated by n - 1 spaces.( 0 ≤ ai < 2^31 )
Then the m lines followed each contain two values Li and Ri.
Output
For each case just output the answers in m lines.
Sample Input
10 105 5 1 3 6 3 5 7 1 73 46 88 92 85 76 71 93 103 105 6
Sample Output
0003104330
这个题目我就是用动态规划来做的。
递推式是:
r[i][j] = r[i + 1][j] - r[i + 1][j - 1] + r[i][j - 1];if (list[i] - list[j] == 1 || list[i] - list[j] == -1)r[i][j]++;
不过有1个问题,n有1万,1万乘以1万的数组不仅仅是超题目给的内存,而是直接就runtime error了。
错误代码:
#include<iostream>#include<string.h>using namespace std;int list[10001];int r[10001][10001];int main(){int n, m;int start, endd;memset(r, 0, sizeof(r));while (cin >> n >> m){for (int i = 1; i <= n; i++)cin >> list[i];for (int j = 2; j <= n; j++){for (int i = j - 1; i >= 1; i--){r[i][j] = r[i + 1][j] - r[i + 1][j - 1] + r[i][j - 1];if (list[i] - list[j] == 1 || list[i] - list[j] == -1)r[i][j]++;}}while (m--){cin >> start >> endd;cout << r[start][endd] << endl;}}return 0;}
于是我只好把r变成1000*1000的数组。
这样,r就只能存储那些2个小标都是10的倍数的区间。
在计算这个r时,递推式略有变化。
假如a<b<c<d,用f来表示最后要求的那个答案,即要输出的数,那么,
f(a,d)=f(a,c)+f(b,d)-f(b,c)+x,其中x是从a到b的区间中选1个数,从c到d的区间选1个数,一共有多少对数满足条件。
在本题里面,用g函数计算x,不过递推式没有上述的递推式那么广泛,
因为仍然是用动态规划做的,所以b-a都是10或者0,d-c都是10或者0。
注意,实际上abcd并不是严格递增的,所以g函数里面sum++的条件必须有i<j
正确的代码:
#include<iostream>#include<string.h>#include<math.h>using namespace std;int list[10001];int r[1001][1001];int g(int s,int e){int sum = 0;for (int i = s; i < s + 10;i++)for (int j = e; j>e - 10;j--)if (i < j && list[i] == list[j] + 1 || list[i] == list[j] - 1)sum++;return sum;}int main(){int n, m;int s, e;int s10, e10;int sum;memset(r, 0, sizeof(r));while (cin >> n >> m){for (int i = 0; i < n; i++)cin >> list[i];for (int j = 1; j <= (n - 1) / 10; j++)for (int i = j - 1; i >= 0; i--)r[i][j] = r[i + 1][j] - r[i + 1][j - 1] + r[i][j - 1] + g(i * 10, j * 10);while (m--){cin >> s >> e;s--;e--;s10 = (s + 9) / 10;e10 = e / 10;sum = r[s10][e10];for (int i = s; i < s10 * 10; i++)for (int j = i + 1; j <= e; j++)if (list[i] == list[j] + 1 || list[i] == list[j] - 1)sum++;for (int j = e10 * 10 + 1; j <= e; j++)for (int i = s10 * 10; i < j;i++)if (list[i] == list[j] + 1 || list[i] == list[j] - 1)sum++;cout << sum << endl;}}return 0;}
- CSU 1515 - Sequence (莫队)
- CSU 1515: Sequence
- CSU 1515 Sequence(莫队算法)
- CSU 1515: Sequence(莫队算法)
- CSU 1515Sequence 莫队算法
- CSU 1555 Inversion Sequence
- csu 1060 Nearest Sequence
- csu 1555: Inversion Sequence(vector)
- CSU 1203 Super-increasing sequence
- CSU - 1203 Super-increasing sequence
- CSU 1203 Super-increasing sequence (模拟)
- CSU 1271: Brackets Sequence(数学啊 )
- CSU-1835 Pry Sequence Transformation(DP)
- CSU 1203: Super-increasing sequence 水题
- CSU 1946 A Rational Sequence (递归)
- CSU 1555 Inversion Sequence 给出逆序数求排列 splay
- CSU 1555-Inversion Sequence(逆序数还原,线段树实现)
- csu 1555 Inversion Sequence 线段树反求逆序数
- cocos2d-x-3.0学习笔记之瓦片地图的使用
- Java单例模式
- ubuntu 14.04LTS下安装sniffit
- 利用 DNS 隧道传递数据和命令来绕过防火墙
- JavaScript 面向对象开发知识总结基础篇
- CSU 1515: Sequence
- 在eclipse下使用maven创建web项目
- C语言::模拟实现strcat函数
- web项目使用jetty容器启动
- Java中系统相关的类:System类、Runtime类
- Firsrt Blood
- 原型模式(Prototype Pattern)
- 用心工作,记录生活,坚持总结,提高自己
- 【PAT】(乙级)1008. 数组元素循环右移问题(20)