找连续数
Accepts: 401
Submissions: 1911
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
解题思路:
长度为N的数组中,遍历所有长度为K的区间,对每个区间进行判断,能否满足“排序后是连续的”,暴力判断是直接排序然后判断,复杂度O(klogk),我把它优化成了复杂度O(k)。
将“排序后是连续的”等价为:“最大最小值相差k-1且所有元素不重复”,找出最大最小值是O(k),所有元素不重复使用哈希的方法,也是O(k)。
还有更好的方法,但既然这么暴力都过了,我也就不管这么多了哈哈……
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
int n, m, k;
cin >> n >> m;
int a[n];
int h[1001];
for(int i = 0; i < n; i++) cin >> a[i];
cout << "Case #1:" << endl;
for(int z = 0; z < m; z++) {
int count = 0;
cin >> k;
if(k == 1) {cout << n << endl;continue;}
int min = a[0], max = a[0];
for(int i = 1; i < k; i++) {
if(a[i] > max) max = a[i];
if(a[i] < min) min = a[i];
}
if(max - min == k - 1) {
bool ok = true;
memset(h, 0, k * sizeof(int));
for(int i = 0; i < k; i++) {
h[a[i]-min] = 1;
}
for(int i = 0; i < k; i++) {
if(h[i] == 0) {
ok = false;
break;
}
}
if(ok) count++;
}
for(int i = 1, iz = i + k - 1; iz < n; i++, iz++) {
if(a[i - 1] != max && a[i - 1] != min) {
if(a[iz] > max) max = a[iz];
if(a[iz] < min) min = a[iz];
}else {
min = a[i];
max = a[i];
for(int j = i + 1; j <= iz; j++) {
if(a[j] > max) max = a[j];
if(a[j] < min) min = a[j];
}
}
if(max - min == k - 1) {
bool ok = true;
memset(h, 0, k * sizeof(int));
for(int j = i; j <= iz; j++) {
h[a[j]-min] = 1;
}
for(int j = 0; j < k; j++) {
if(h[j] == 0) {
ok = false;
break;
}
}
if(ok) count++;
}
}
cout << count << endl;
}
}