Codeforces Round #320 (Div. 2) [Bayan Thanks-Round]

 

数学 A - Raising Bacteria

分析:如果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;
}

 

贪心 B - Finding Team Member

题意:每两个人组成一个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;
}

 

转载于:https://www.cnblogs.com/Running-Time/p/4818822.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值