93. 递归实现组合型枚举
简单递归。因为要从字典序从小到大排序。
// Problem: 递归实现组合型枚举
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/95/
// Memory Limit: 256 MB
// Time Limit: 5000 ms
// Date:2021-10-06 09:51:47
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int inf = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;
int n, m, T;
int flag;
int a[50];
void dg(int num,int si) {
if (si == m) {
for (int i=0;i<si;i++) {
cout << a[i] << " ";
}
cout << endl;
return;
}
if (num > n) {
return;
}
a[si]=num;
dg(num + 1,si+1);
dg(num + 1, si);
}
int main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
dg(1,0);
return 0;
}
94. 递归实现排列型枚举
简单dfs
// Problem: 递归实现排列型枚举
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/96/
// Memory Limit: 256 MB
// Time Limit: 5000 ms
// Date:2021-10-06 19:03:14
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int inf=0x3f3f3f3f;
const int MAXN=1e5+10;
int n,m,T;
int flag;
int a[20];
int vis[10];
void dfs(int num){
if(num==n){
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
return;
}
for(int i=1;i<=n;i++){
if(!vis[i]){
vis[i]=1;
a[num]=i;
dfs(num+1);
vis[i]=0;
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
dfs(0);
return 0;
}
95. 费解的开关
之前写过一个类似的题目。
http://poj.org/problem?id=3279
是一个思维题,也用到了状态压缩。
因为这个题目规定了是5*5的范围。
所以是第一排开和不开有32种状态。
遍历这32种状态。然后再来分析题目。
因为 开关一个灯会影响周围。
所以直接当做下面的灯影响上面的灯即可,
即上面的灯是暗的就需要下面的灯开关一次,然后再影响周围和下面的灯。
所以可以一排一排的遍历。如果这一排的一个灯是暗的,就操作这个灯的下一层的灯即可。
然后最后一排因为下面没有灯了。就遍历最后一排,如果全是亮的则符合一个条件,这时候再来判断开关次数即可。
// Problem: 费解的开关
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/97/
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// Date:2021-10-06 19:16:40
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int inf = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;
int n, m, T;
int flag;
string str[10];
void change(int x, int y, string s[]) {
for(int i=y-1;i<=y+1;i++){
if(i>=0&&i<5){
s[x][i]^=1;
}
}
if(x==4)return;
s[x+1][y]^=1;
}
int ok(int k, string s[])
{
int step = 0;
for (int i = 0; i < 5; i++) {
// cout<<(k>>i&1);
if (k >> i & 1) {
step++;
change(0,i,s);
}
}
// cout<<" ";
// cout<<s[0]<<endl;
// for(int i=0;i<4;i++){
// if(s[0][i]=='0'){
// return 7;
// }
// }
for(int i=0;i<4;i++){
for(int j=0;j<5;j++){
if(s[i][j]=='0'){
step++;
change(i+1,j,s);
}
}
}
int flag=1;
for(int i=0;i<5;i++){
if(s[4][i]=='0'){
flag=0;
break;
}
}
if(flag){
return step;
}
return 1000;
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T--) {
for (int i = 0; i < 5; i++) {
cin >> str[i];
}
string s[10];
int ans = 4000;
for (int k = 0; k < 32; k++) {
for (int i = 0; i < 5; i++) {
s[i] = str[i];
}
ans = min(ok(k, s), ans);
// cout<<ans<<" ";
}
if (ans > 6)
cout << -1 << endl;
else
cout << ans << endl;
}
return 0;
}