题意
http://www.nocow.cn/index.php/Translate:Sgu/108,翻译版,这里不再多说。
思路
这个题刚到手其实都是会写的,但是一般交上去会发现爆内存,原因就是我们用来判定self number的数组开太大了,要想减少空间复杂度只能从这个数组入手,那么我们真的需要那么大的数组么?显然是不用的,通过本题的数据范围可以发现N最大为7位数,即使7位全是9,我们能够更新到的数组区域长度也仅为63个单位,所以我们把bool标记数组开个63长度就够了,开100那更是没问题,这个技巧就是所谓的“滚动数组”。
滚动数组的操作方法有几点:1.通过求余来确定位置 2.使用完当前位置后,要给它初始化为没有使用过的样子以便以后的元素正常使用。
仅仅使用滚动数组还不足以完成这个题,还要注意输出答案的方式,因为数组在滚动,所以你不可能在完成判定之后再输出结果,而是应该边滚动判定,边记录,最后把记录的输出去。
本题有几个坑点:首先你要把输出的目标索引排个序,否则如果数据是乱序的基本都会跪,其次要注意请求的索引中是有重复的,可能一个索引被请求了多次。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#include <iostream> #include <algorithm> #include <queue> #include <vector> #include <cstdlib> #include <cstdio> #include <string> #include <cstring> #include <ctime> #include <iomanip> #include <cmath> #include <set> #include <stack> #include <cmath> using namespace std; bool isself[100]; vector<pair<int, int> > goal; int container[5005]; bool cmp(pair<int, int> a,pair<int, int> b){ return a.first < b.first; } int main(){ int n = 0,k = 0; scanf(" %d %d",&n,&k); goal.clear(); for (int i = 1; i <= k; i++) { int tmp = 0; scanf(" %d",&tmp); goal.push_back(make_pair(tmp, i)); } sort(goal.begin(), goal.end(),cmp); memset(isself, true, sizeof(isself)); memset(container, 0, sizeof(container)); int cnt = 0; int cur = 0; for (int i = 1; i <= n; i++) { if (isself[i%64]) { cnt++; while (cnt == goal[cur].first) { container[goal[cur].second] = i; cur++; } } int tmp = i,sum = i; while (tmp != 0) { sum += tmp%10; tmp /= 10; } isself[sum%64] = false; isself[i%64] = true; } printf("%d\n",cnt); for (int i = 1;i < k; i++) { printf("%d ",container[i]); } printf("%d\n",container[k]); return 0; } |