n个人围成一圈,相邻的人是好朋友必须拉着的手上的数互质 也就是说 这个人的右手的数 和下一个人 左手的数互质
求多少种可能? 同一个环不重复计数
思路:
1 2 3 4假如围成一圈 那么 2 3 4 1也互质 1的右手由第一个圈可知已经和2的左手互质了
同理可以推出 3 4 1 2、4 1 2 3也是这样
所以我们如果我们任意爆搜开始的第一个人话 可搜出重复的 那么我们可不可以固定第一个人呢
显然是可以的 我们上面已经得证了
trick: 1个人的时候 是没有朋友的 即n = 1, ans = 0;
参考code:
// // Created by TaoSama on 2015-05-29 // Copyright (c) 2015 TaoSama. All rights reserved. // #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int N = 1e5 + 10; int n, ans, l[15], r[15]; bool vis[15]; void dfs(int dep, int last, int first) { if(dep == n + 1) { if(__gcd(l[first], r[last]) == 1) { /*for(int i = 0; i < n; ++i) { char c = cur[0]; cur.erase(0, 1); cur += c; if(s.count(cur)) return; }*/ //s.insert(cur); ++ans; } return; } for(int i = 2; i <= n; ++i) { if(!vis[i]) { if(__gcd(l[i], r[last]) == 1) { vis[i] = true; dfs(dep + 1, i, first); vis[i] = false; } } } } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d", &n) == 1) { //s.clear(); memset(vis, false, sizeof vis); for(int i = 1; i <= n; ++i) scanf("%d%d", l + i, r + i); ans = 0; if(n != 1) dfs(2, 1, 1); else ans = 0; printf("%d\n", ans); /*for(auto i : s) { cout << i << endl; }*/ } return 0; }
Alice和Bob A和B玩游戏 A先手 B必须走A旁边的四个格子 谁不能走了 谁就输了
思路:
根据博弈论的思想: 如果A必赢 那么接下来所有的情况中 B都必须输
如果A必输 那么接下来所有的情况中 必定包含一种B赢的情况
那么搜一下就好了
参考code:
// // Created by TaoSama on 2015-05-30 // Copyright (c) 2015 TaoSama. All rights reserved. // #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int N = 1e5 + 10; int n, m, d[][2] = { -1, 0, 0, -1, 1, 0, 0, 1}; char a[8][8]; bool dfs(int x, int y) { for(int i = 0; i < 4; ++i) { int nx = x + d[i][0], ny = y + d[i][1]; if(nx < 1 || nx > n || ny < 1 || ny > m || a[nx][ny] == '*') continue; a[x][y] = '*'; bool sub = dfs(nx, ny); a[x][y] = '.'; if(sub) return false; //子局面有赢的就输了 } return true; //子局面都输说明赢了 } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d%d", &n, &m) == 2) { for(int i = 1; i <= n; ++i) scanf("%s", a[i] + 1); bool win = false; for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { if(a[i][j] == '.' && dfs(i, j)) { win = true; break; } } if(win) break; } puts(win ? "Alice" : "Bob"); } return 0; }
// // Created by TaoSama on 2015-05-29 // Copyright (c) 2015 TaoSama. All rights reserved. // #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int N = 1e5 + 10; const double EPS = 1e-10; int a[5]; void dfs(int dep, double ans, double cur) { if(dep == 5) { if(abs(ans + cur - 24) < EPS || abs(ans - cur - 24) < EPS || abs(ans * cur - 24) < EPS) throw true; if(abs(cur) > EPS && abs(ans / cur - 24) < EPS) throw true; return; } dfs(dep + 1, ans + cur, a[dep + 1]); dfs(dep + 1, ans - cur, a[dep + 1]); dfs(dep + 1, ans * cur, a[dep + 1]); if(abs(cur) > EPS) dfs(dep + 1, ans / cur, a[dep + 1]); dfs(dep + 1, ans, cur + a[dep + 1]); dfs(dep + 1, ans, cur - a[dep + 1]); dfs(dep + 1, ans, cur * a[dep + 1]); if(abs(a[dep + 1]) > EPS) dfs(dep + 1, ans, cur / a[dep + 1]); } int main() { #ifdef LOCAL // freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); while(t--) { for(int i = 1; i <= 4; ++i) scanf("%d", a + i); sort(a + 1, a + 5); try { do { dfs(2, a[1], a[2]); } while(next_permutation(a + 1, a + 5)); puts("no"); } catch(bool) { puts("yes"); } } return 0; }
// // Created by TaoSama on 2015-06-03 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int N = 1e5 + 10; long long n, m, last, ans; bool vis[10]; vector<char> have; map<char, int> mp, zero; string a[15]; void dfs(int k) { if(k == last) { //to check the last digits is legal or not long long sum = 0; for(int i = 1; i <= n; ++i) { char &c = a[i][a[i].size() - 1]; if(i != n) sum += mp[c]; else { if(sum % 10 != mp[c]) return; } } } if(k == m) { //to check the whole equation is legal or not long long sum = 0; for(int i = 1; i <= n; ++i) { long long t = 0; for(int j = 0; j < a[i].size(); ++j) { char &c = a[i][j]; t = t * 10 + mp[c]; } if(i != n) sum += t; else { if(sum == t) ++ans; } } return; } for(int i = 0; i < 10; ++i) { if(vis[i] || i == 0 && zero[have[k]]) continue; vis[i] = true; mp[have[k]] = i; dfs(k + 1); vis[i] = false; } } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(cin >> n) { memset(vis, false, sizeof vis); have.clear(); mp.clear(); zero.clear(); //save the last digits first for(int i = 1; i <= n; ++i) cin >> a[i]; for(int i = 1; i <= n; ++i) { char &c = a[i][a[i].size() - 1]; if(!mp.count(c)) { mp[c] = have.size(); have.push_back(c); } } last = have.size(); //save the other digits then for(int i = 1; i <= n; ++i) { for(int j = 0; j < a[i].size() - 1; ++j) { char &c = a[i][j]; if(j == 0) zero[c] = 1; //save the nonzero character if(!mp.count(c)) { mp[c] = have.size(); have.push_back(c); } } } m = have.size(); ans = 0; if(m <= 10) dfs(0); cout << ans << '\n'; } return 0; }
// // Created by TaoSama on 2015-05-29 // Copyright (c) 2015 TaoSama. All rights reserved. // #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int N = 1e5 + 10; typedef long long LL; int n; LL W, w[45]; pair<LL, LL> ps[1 << 20]; int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d%lld", &n, &W) == 2) { for(int i = 0 ; i < n; ++i) scanf("%lld", w + i); int n2 = n >> 1; for(int i = 0; i < 1 << n2; ++i) { LL sw = 0, sv = 0; for(int j = 0; j < n2; ++j) { if(i >> j & 1) { sw += w[j]; sv += w[j]; } } ps[i] = make_pair(sw, sv); } sort(ps, ps + (1 << n2)); int m = 1; for(int i = 1; i < 1 << n2; ++i) { if(ps[m - 1].second < ps[i].second) { ps[m++] = ps[i]; } } LL ans = 0; for(int i = 0; i < 1 << (n - n2); ++i) { LL sw = 0, sv = 0; for(int j = 0; j < n - n2; ++j) { if(i >> j & 1) { sw += w[n2 + j]; sv += w[n2 + j]; } } if(sw <= W) { LL tv = (lower_bound(ps, ps + m, make_pair(W - sw, (LL)INF)) - 1)->second; ans = max(ans, sv + tv); } } printf("%lld\n", ans); } return 0; }
发现直到15都找到了 16 17爆栈了 这里贴出前8个
说明我们的猜想完全可行 那么我们来也许证明下 我胡扯的
(
- - 根据鸽笼原理 超过2^k长度 本来串的可能就只有2^k个 超过了说明必然会形成循环
那么就出现了相同的子串 与题目要求违背 那么最大长度就是2^k ■
)
证明:
我们把每连着的k个数字当成一个点,每个点的出边有两条,因为下一个数字可能是0可能是1
入边同理也是两条,因为上一个数字可能是0可能是1
然后我们发现每个点的出度=入度,而这恰好是欧拉图的判定条件
所以原图是欧拉图,必然存在一条欧拉回路
那么第一问必然可以取到最大的2^k (官方题解写的 - -)
这么暴力的搜索必然会爆栈 - - 2^(2^k) = 这个数大的可怕了
所以我们来找找规律 观察上面的图发现
对于每个要求的k的求出的合理的2^k大小的串 它的开头是0000... 结尾是1111...
我们来数一下 咦? 好像大小是k耶~
那么我们大胆猜想 所求串的开头一定是k个0 结尾一定是k个1
所以 - - 重新写出一个搜索这回就不会爆栈啦~ 然后我们得到了AC
参考code:
// // Created by TaoSama on 2015-05-29 // Copyright (c) 2015 TaoSama. All rights reserved. // #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int N = 1 << 17; int n, m, l; bool vis[N + 5], a[N + 5]; bool dfs(int k, int v) { if(k == l) return true; v = (v % m) << 1; if(!vis[v] && k <= l - n) { vis[v] = true; a[k] = 0; bool F = dfs(k + 1, v); vis[v] = false; if(F) return true; } int w = v + 1; if(!vis[w]) { vis[w] = true; a[k] = 1; bool F = dfs(k + 1, w); vis[w] = false; if(F) return true; } return false; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d", &n) == 1) { l = 1 << n; m = l >> 1; memset(vis, false, sizeof vis); for(int i = 1; i <= n; ++i) { a[i] = 0; a[l - i + 1] = 1; } vis[0] = vis[(1 << n) - 1] = true; dfs(n + 1, 0); printf("%d\n", l); for(int i = 1; i <= l; ++i) printf("%d", a[i]); puts(""); } return 0; } /* 暴力找规律代码(事实连linux都爆栈 数真大): // // Created by TaoSama on 2015-05-29 // Copyright (c) 2015 TaoSama. All rights reserved. // #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int N = 1 << 17; int n, m, l; bool vis[N + 5], a[N + 5]; bool dfs(int k, int v) { if(k == l + 1) { int w = (v % m) << 1, t = w; for(int i = 1; i < n; ++i) { w += a[i]; if(vis[w]) { for(int j = 1; j <= i; ++j) { t += a[j]; vis[t] = false; t = (t % m) << 1; } return false; } w = (w % m) << 1; } return true; } v = (v % m) << 1; for(int i = 0; i <= 1; ++i) { int w = v + i; if(k >= n && vis[w]) continue; a[k] = i; if(k >= n) vis[w] = true; bool F = dfs(k + 1, w); if(k >= n) vis[w] = false; if(F) return true; } return false; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d", &n) == 1) { l = 1 << n; m = l >> 1; memset(vis, false, sizeof vis); dfs(1, 0); printf("%d\n", l); for(int i = 1; i <= l; ++i) printf("%d", a[i]); puts(""); } return 0; } */