搜索
搜索大法好
小木棍:https://www.luogu.org/problem/P1120
这数据也太加强了吧qaq
优化:对木棍排序,显然先用长度大的;枚举可能长度时,可能长度是总长度的因数
然后就是重头戏:如果在一开始,你加入当前最大的木棍,然后你失败了,那么目前为止的方案肯定就不行了,因为这个最大木棍再也没有被用的机会了
同理,如果你用当前最大填满了,在下一轮中你又失败了,这个肯定也不行
还有要记得unique啥的,不然扩展层数太多
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<queue> #include<map> using namespace std; typedef long long ll; //typedef int mainint; //#define int long long typedef double db; #define pii pair<int,int> #define mp make_pair #define llinf 9000000000000000000LL #define inf 0x3f3f3f3f #define B cout << "breakpoint" << endl; #define clr(a) memset(a,0,sizeof(a)); #define O(x) cout << #x << " " << (x) << endl; inline int read() { int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { (ans *= 10) += ch - '0'; ch = getchar(); } return ans * op; } int n,a[100],sum,L,tot; bool flag,ok; int vis[101]; bool cmp(int a,int b) { return a > b; } void dfs(int cur,int len,int tot) { //if(L == 6) printf("%d %d %d\n",cur,len,tot); if(tot == 0) { printf("%d",L); exit(0); } else if(cur == n + 1 && len == L) return (void)dfs(1,0,tot - 1); for(int i = cur;i <= n;i++) { if(!vis[a[i]]) continue; if(len + a[i] > L) continue; vis[a[i]]--; if(len + a[i] == L) dfs(1,0,tot - 1); else dfs(i,len + a[i],tot); vis[a[i]]++; if(len == 0 || len + a[i] == L) return; } } int main() { n = read(); int mx = 0; for(int i = 1;i <= n;i++) { int x = read(); if(x > 50) continue; a[++tot] = x; vis[x]++; sum += a[tot],mx = max(a[tot],mx); } n = tot; sort(a + 1,a + 1 + n,cmp); tot = unique(a + 1,a + 1 + n) - a - 1; n = tot; for(int i = mx;i <= sum;i++) { if(sum % i) continue; L = i; ok = flag = 0; dfs(1,0,sum / i); } }
N皇后:https://www.luogu.org/problem/P1562
维护三个状态:列、左对角线,右对角线,二进制维护
每到下一层,左对角线左移,右对角线右移(画图即可
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<queue> #include<map> using namespace std; typedef long long ll; //typedef int mainint; //#define int long long typedef double db; #define pii pair<int,int> #define mp make_pair #define llinf 9000000000000000000LL #define inf 0x3f3f3f3f #define B cout << "breakpoint" << endl; #define clr(a) memset(a,0,sizeof(a)); #define O(x) cout << #x << " " << (x) << endl; inline int read() { int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { (ans *= 10) += ch - '0'; ch = getchar(); } return ans * op; } int n,a[101]; int last,ans; inline int lowbit(int x) { return x & (-x); } void dfs(int cur,int col,int sl,int sr) { if(cur == n + 1) return (void)(ans += (col == last)); int pos = (~(col | sl | sr | a[cur])) & last; while(pos) { int p = lowbit(pos); pos = pos ^ p; dfs(cur + 1,col | p,(sl | p) << 1,(sr + p) >> 1); } } int main() { n = read(); last = (1 << n) - 1; for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++) { a[i] <<= 1; char c; cin >> c; if(c == '.') a[i] |= 1; } dfs(1,0,0,0); printf("%d",ans); }
骑士精神:https://www.luogu.org/problem/P2324
假的A*
考虑下界剪枝,设置估价函数e,IDA*即可
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<queue> #include<map> using namespace std; typedef long long ll; //typedef int mainint; //#define int long long typedef double db; #define llinf 9000000000000000000LL #define inf 0x3f3f3f3f #define B cout << "breakpoint" << endl; #define clr(a) memset(a,0,sizeof(a)); #define O(x) cout << #x << " " << (x) << endl; inline int read() { int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { (ans *= 10) += ch - '0'; ch = getchar(); } return ans * op; } const int dx[]={0,1,1,-1,-1,2,2,-2,-2}; const int dy[]={0,2,-2,2,-2,1,-1,1,-1}; const int goal[7][7]={ {0,0,0,0,0,0}, {0,1,1,1,1,1}, {0,0,1,1,1,1}, {0,0,0,2,1,1}, {0,0,0,0,0,1}, {0,0,0,0,0,0} }; bool ok; int mp[7][7]; inline int e() { int res = 0; for(int i = 1;i <= 5;i++) for(int j = 1;j <= 5;j++) if(mp[i][j] != goal[i][j]) res++; return res; } void dfs(int dep,int x,int y,int mdep) { if(dep == mdep) return (void)(ok = (e() == 0)); for(int i = 1;i <= 8;i++) { if(ok) return; int nx = x + dx[i],ny = y + dy[i]; if(nx < 1 || nx > 5 || ny < 1 || ny > 5) continue; swap(mp[x][y],mp[nx][ny]); if(dep + e() <= mdep) dfs(dep + 1,nx,ny,mdep); swap(mp[x][y],mp[nx][ny]); } } int main() { int t = read(); while(t--) { ok = 0; int sx,sy; char x; for(int i = 1;i <= 5;i++) for(int j = 1;j <= 5;j++) { cin >> x; if(x == '*') mp[i][j] = 2,sx = i,sy = j; else mp[i][j] = x - '0'; } if(!e()) {printf("0\n"); continue; } for(int i = 1;i <= 15;i++) { dfs(0,sx,sy,i); if(ok) { printf("%d\n",i); break; } } if(!ok) printf("-1\n"); } }