Codeforces Round #320 (Div. 2) [Bayan Thanks-Round]
分析:如果1 << k == x,那么放1个就可以了;否则还要加上差值的二进制的1的个数。
/************************************************ * Author :Running_Time * Created Time :2015/9/16 星期三 23:13:08 * File Name :A.cpp ************************************************/ #include <cstdio> #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string> #include <vector> #include <queue> #include <deque> #include <stack> #include <list> #include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 typedef long long ll; const int N = 1e5 + 10; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int main(void) { int x; scanf ("%d", &x); int i = 1; while (i < x) { i <<= 1; } if (i == x) { printf ("%d\n", 1); } else { int ans = 1; i >>= 1; int y = x - i; while (y) { if (y & 1) ans++; y >>= 1; } printf ("%d\n", ans); } return 0; }
题意:每两个人组成一个team,两人之间有一个连接的强度,问所有人连接强度最大的team组合是怎样的
分析:按照连接强度排序,因为连接强度无重复。如果该连接强度连接的两个人没有组成team,那么他们就组成team,这样的选择是连接强度最大的
总结:这题的贪心方法没想到,按照每个人能连接的人的连接强度排序WA了
/************************************************ * Author :Running_Time * Created Time :2015/9/16 星期三 23:13:11 * File Name :B.cpp ************************************************/ #include <cstdio> #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string> #include <vector> #include <queue> #include <deque> #include <stack> #include <list> #include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 typedef long long ll; const int N = 8e2 + 10; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; struct Team { int u, v, w; Team (int u = 0, int v = 0, int w = 0) : u (u), v (v), w (w) {} bool operator < (const Team &r) const { return w > r.w; } }t[N*N]; int ans[N]; int main(void) { int n; scanf ("%d", &n); int m = n * 2; int tot = 0; for (int i=2; i<=m; ++i) { for (int x, j=1; j<=i-1; ++j) { scanf ("%d", &x); t[++tot] = Team (i, j, x); } } sort (t+1, t+1+tot); memset (ans, 0, sizeof (ans)); for (int i=1; i<=tot; ++i) { int u = t[i].u, v = t[i].v; if (!ans[u] && !ans[v]) { ans[u] = v; ans[v] = u; } } for (int i=1; i<=m; ++i) { printf ("%d%c", ans[i], i == m ? '\n' : ' '); } return 0; }
二分 C - A Problem about Polyline
题意:有一个(0, 0) – (x, x) – (2x, 0) – (3x, x) – (4x, 0) – ... - (2kx, 0) – (2kx + x, x) – 的折线,问(a, b)是否在折线上
分析:两种情况,点在某个三角形的左边:a = 2 * k * x + b,或者在右边:a = 2 * k * x - b,满足x >= b,二分查找k
/************************************************ * Author :Running_Time * Created Time :2015/9/16 星期三 23:13:14 * File Name :C.cpp ************************************************/ #include <cstdio> #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string> #include <vector> #include <queue> #include <deque> #include <stack> #include <list> #include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 typedef long long ll; const int N = 1e5 + 10; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int main(void) { //UNAC double a, b; scanf ("%lf%lf", &a, &b); if (a < b) puts ("-1"); else { double ans = 1e9 + 10; int l = 1, r = 1e9; while (l <= r) { int mid = (l + r) / 2; double xx = (a - b) / (double) (2 * mid); if (xx >= b) { ans = min (ans, xx); l = mid + 1; } else r = mid - 1; } l = 1, r = 1e9; while (l <= r) { int mid = (l + r) / 2; double xx = (a + b) / (double) (2 * mid); if (xx >= b) { ans = min (ans, xx); l = mid + 1; } else r = mid - 1; } printf ("%.9f\n", ans); } return 0; }
贪心+位运算 D - "Or" Game
题意:可以对n个数字其中的数字*x,最多k次,问 的最大值
分析:其决定因素的是二进制的最高位,如果ai*x,那么剩下的所有x都给ai,降低复杂度使用前缀和后缀,枚举选取ai得到最大值
/************************************************ * Author :Running_Time * Created Time :2015/9/17 星期四 17:21:00 * File Name :D.cpp ************************************************/ #include <cstdio> #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string> #include <vector> #include <queue> #include <deque> #include <stack> #include <list> #include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 typedef long long ll; const int N = 2e5 + 10; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; ll a[N], prefix[N], suffix[N]; int main(void) { int n, k, x; scanf ("%d%d%d", &n, &k, &x); for (int i=1; i<=n; ++i) scanf ("%I64d", &a[i]); ll y = 1; for (int i=1; i<=k; ++i) y *= x; for (int i=1; i<=n; ++i) { prefix[i] = prefix[i-1] | a[i]; } for (int i=n; i>=1; --i) { suffix[i] = suffix[i+1] | a[i]; } ll ans = 0; for (int i=1; i<=n; ++i) { ans = max (ans, prefix[i-1] | (a[i] * y) | suffix[i+1]); } printf ("%I64d\n", ans); return 0; }
三分||二分 E - Weakness and Poorness
题意:n个数字,每个数字减去x,使得求最大连续子序列和最小连续子序列的绝对值的最大值最小
分析:x增加,最大连续子序列f(x)递减,最小连续子序列g(x)递增,可用三分。二分的没想明白,先放着
三分:
/************************************************ * Author :Running_Time * Created Time :2015/9/17 星期四 17:56:57 * File Name :E.cpp ************************************************/ #include <cstdio> #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string> #include <vector> #include <queue> #include <deque> #include <stack> #include <list> #include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 typedef long long ll; const int N = 2e5 + 10; const double INF = 1e10; const int MOD = 1e9 + 7; double a[N], b[N]; int n; double cal_max(void) { double sum = 0, mx = 0; for (int i=1; i<=n; ++i) { sum = max (sum + b[i], b[i]); if (sum > mx) mx = sum; } return mx; } double cal_min(void) { double sum = 0, mn = INF; for (int i=1; i<=n; ++i) { sum = min (sum + b[i], b[i]); if (sum < mn) mn = sum; } return mn; } double cal(double x) { for (int i=1; i<=n; ++i) b[i] = a[i] - x; return max (cal_max (), -cal_min ()); } int main(void) { scanf ("%d", &n); for (int i=1; i<=n; ++i) scanf ("%lf", &a[i]); double l = -INF, r = INF; for (int i=1; i<=200; ++i) { double mid = (l + r) / 2; double lmid = (l + mid) / 2; double rmid = (r + mid) / 2; if (cal (lmid) < cal (rmid)) r = rmid; else l = lmid; } printf ("%.10f\n", cal ((l + r) / 2)); return 0; }
二分:
/************************************************ * Author :Running_Time * Created Time :2015/9/17 星期四 17:56:57 * File Name :E.cpp ************************************************/ #include <cstdio> #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string> #include <vector> #include <queue> #include <deque> #include <stack> #include <list> #include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 typedef long long ll; const int N = 2e5 + 10; const double INF = 1e10; const int MOD = 1e9 + 7; double a[N], b[N]; int n; double cal_max(void) { double sum = 0, mx = 0; for (int i=1; i<=n; ++i) { sum = max (sum + b[i], b[i]); if (sum > mx) mx = sum; } return mx; } double cal_min(void) { double sum = 0, mn = INF; for (int i=1; i<=n; ++i) { sum = min (sum + b[i], b[i]); if (sum < mn) mn = sum; } return mn; } bool check(double x) { for (int i=1; i<=n; ++i) b[i] = a[i] - x; double A = cal_max (); double B = cal_min (); return (-B > A); } int main(void) { scanf ("%d", &n); for (int i=1; i<=n; ++i) scanf ("%lf", &a[i]); double l = -INF, r = INF; for (int i=1; i<=200; ++i) { double mid = (l + r) / 2; if (check (mid)) r = mid; else l = mid; } for (int i=1; i<=n; ++i) b[i] = a[i] - l; printf ("%.10f\n", cal_max ()); return 0; }
编译人生,运行世界!