生活随笔
收集整理的這篇文章主要介紹了
『ACM-算法-枚举法』信息竞赛进阶指南--枚举方法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
你以為枚舉是一個一個的找?
還真是
你以為枚舉都是for循環?
還真是
但你真的會枚舉嗎?組合型枚舉,指數型枚舉,排列型枚舉?難道你只會線形枚舉?
你可太菜了!
vector
<int> chosen
;
void calc(int x
) {if (x
== n
+ 1) {for (int i
= 0; i
< chosen
.size(); i
++)printf("%d ", chosen
[i
]);puts("");return;}calc(x
+ 1);chosen
.push_back(x
);calc(x
+ 1);chosen
.pop_back();
}
vector
<int> chosen
;
void calc(int x
) {if (chosen
.size() > m
|| chosen
.size() + (n
- x
+ 1) < m
) return;if (x
== n
+ 1) {for (int i
= 0; i
< chosen
.size(); i
++)printf("%d ", chosen
[i
]);puts("");return;}calc(x
+ 1);chosen
.push_back(x
);calc(x
+ 1);chosen
.pop_back();
}
int order
[20];
bool chosen
[20];
void calc(int k
) {if (k
== n
+ 1) {for (int i
= 1; i
<= n
; i
++)printf("%d ", order
[i
]);puts("");return;}for (int i
= 1; i
<= n
; i
++) {if (chosen
[i
]) continue;order
[k
] = i
;chosen
[i
] = 1;calc(k
+ 1);chosen
[i
] = 0;order
[k
] = 0;}
}
vector
<int> chosen
;
int stack
[100010], top
= 0, address
= 0;void call(int x
, int ret_addr
) { int old_top
= top
;stack
[++top
] = x
; stack
[++top
] = ret_addr
; stack
[++top
] = old_top
;
}int ret() { int ret_addr
= stack
[top
- 1];top
= stack
[top
]; return ret_addr
;
}int main() {int n
, m
;cin
>> n
>> m
;call(1, 0); while (top
) {int x
= stack
[top
- 2]; switch (address
) {case 0:if (chosen
.size() > m
|| chosen
.size() + (n
- x
+ 1) < m
) {address
= ret(); continue;}if (x
== n
+ 1) {for (int i
= 0; i
< chosen
.size(); i
++)printf("%d ", chosen
[i
]);puts("");address
= ret(); continue;}call(x
+ 1, 1); address
= 0;continue; case 1:chosen
.push_back(x
);call(x
+ 1, 2); address
= 0;continue; case 2:chosen
.pop_back();address
= ret(); }}
}
總結
以上是生活随笔為你收集整理的『ACM-算法-枚举法』信息竞赛进阶指南--枚举方法的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。