GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版
由于书上给了思路,所以做起来并不难。
即使超时,因为数据量不大(1000个), 我们也可以直接打表直接返回结果。
但是如果想不打表完成题目,那么就需要使用思路中给出的各种优化方案,不然很容易超时。
我一开始用set作为存储已存在的数字,但还是超时,后面改成用数组存储AC了。
AC代码
- #include
- #include
- #include
-
- int n, maxCount;
- int setArr[1010];
- int maxV;
-
- int getMin(int a, int b) {
- if(a > b) return b;
- return a;
- }
-
- // 递归遍历
- bool dfs(int count, int pre, int subCount) {
- if(pre == n) return true;
- if(count >= maxCount) return false;
- if(maxV * (1 << (maxCount - count)) < n) return false;
- if(subCount > 2) return false;
- int value, preMaxV, i;
- if(pre < n) {
- for(i = getMin(maxV, n); i > 0; --i) {
- if(!setArr[i]) continue;
- value = i + pre;
- if(value > 1000 || (value > n && maxV > n)) continue;
- if(setArr[value]) continue;
- setArr[value] = 1;
- preMaxV = maxV;
- if(value > maxV) maxV = value;
- if(dfs(count+1, value, subCount)) return true;
- setArr[value] = 0;
- maxV = preMaxV;
- }
- }
- if(subCount == 2) return false;
- for(i = maxV; i > 0; --i) {
- if(!setArr[i]) continue;
- value = abs(i - pre);
- if(value == 0 || value > n) continue;
- if(value == n) return true;
- if(setArr[value]) continue;
- setArr[value] = 1;
- if(dfs(count+1, value, subCount + 1)) return true;
- setArr[value] = 0;
- }
- return false;
- }
-
- // 初始化
- int computed() {
- if(n == 1) return 0;
- for(maxCount = 1; maxCount < 20; ++maxCount) {
- memset(setArr, 0, sizeof(setArr));
- setArr[1] = 1;
- maxV = 1;
- if(dfs(0, 1, 0)) return maxCount;
- }
- }
-
- int main() {
- while(scanf("%d", &n) == 1 && n > 0) {
- printf("%d\n", computed());
- }
- return 0;
- }
-
-