2013 南京邀请赛 A,C,H, K

A题:求期望,先统计出每次得分期望,然后如果获得再一次机会,下次期望为n / m * 期望,n为总个数,m为在一次的个数,然后利用等比数列前

n项和的公式去算即可,要注意特判一下可能出现inf的情况,即期望不为0,且n / m = 1。

C题:a,b范围内,把每个数字拆成32位,计算0-a每位多少个1,0-b每位多少个1,相减后在去计算总进位次数即可

H题:签到题,找出重复数字。

K题:数论,求是否存在ID % X1 属于[Y1,Z1] && ID % X2 属于[Y2, Z2], 设ID % X1 = u, ID % X2 = v, ID / X1 = a, ID / X2 = b; 那么Id - x1 * a = u, id - x2 * b = v;

x2 * b - x1 * a = u - v; 这样就变成了a * x + b *y  = c判断有无整数解,欧几里德定理,只要c是gcd(a,b)的整数倍即可。

那么t = gcd(x1, x2), u - v的范围可以求出来为[y1 - z2, z1 - y2],然后判断一下是不是整数倍即可

代码:

A:

#include <cstdio>
#include <cstring>
#include <cmath>
const double esp = 1e-9;
const int N = 205;

int n, m, tmp, vis[N];
double num, sum, mm;

int main() {
    while (~scanf("%d", &n)) {
	sum = 0; mm = 0;
	memset(vis, 0, sizeof(vis));
	for (int i = 0; i < n; i++) {
	    scanf("%lf", &num);
	    sum += num;
	}
	sum /= n;
	scanf("%d", &m);
	while (m--) {
	    scanf("%d", &tmp);
	    if (!vis[tmp]) mm++;
	    vis[tmp] = 1;
	}
	mm /= n;
	if (fabs(sum) < esp)
	    printf("0.00\n");
	else if (fabs(sum) >= esp && fabs(mm - 1) < esp)
	    printf("inf\n");
	else printf("%.2lf\n", sum / (1 - mm));
    }
    return 0;
}

C:

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 35;
long long a, b;
long long d1[N], d2[N], mi[N];

void init() {
    mi[0] = 1;
    for (int i = 1; i <= 32; i++)
	mi[i] = mi[i - 1] * 2;
}

void build(long long *d, long long num) {
    for (int i = 0; i < 32; i++) {
	long long c = num / mi[i + 1];
	long long yu = num % mi[i + 1] - mi[i];
	if (yu < 0) yu = 0;
	d[i] = c * mi[i] + yu;
    }
}

int main() {
    init();
    while (cin >> a >> b) {
	memset(d1, 0, sizeof(d1));
	memset(d2, 0, sizeof(d2));
	build(d1, a);
	build(d2, b + 1);
	for (int i = 0; i < 32; i++)
	    d2[i] -= d1[i];
	long long s = 0, ans = 0;
	for (int i = 0; i < 32; i++) {
	    s = (d2[i] + s) / 2;
	    ans += s;
	}
	while (s) {
	    s /= 2;
	    ans += s;
	}
	cout << ans << endl;
    }
    return 0;
}

H:

#include <stdio.h>
#include <string.h>

const int N = 1005;
int n, num, vis[N];

int main() {
    while (~scanf("%d", &n)) {
	memset(vis, 0, sizeof(vis));
	for (int i = 0; i <= n; i++) {
	    scanf("%d", &num);
	    vis[num]++;
	    if (vis[num] == 2)
		printf("%d\n", num);
	}
    }
    return 0;
}

K:

#include <stdio.h>
#include <string.h>

const int N = 1005;
int n, x[N], y[N], z[N];

int gcd(int a, int b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}

bool judge(int t, int l, int r) {
    if (l % t == 0 || r % t == 0) return true;
    if (l < 0 && r >= 0) return true;
    if (r / t - l / t > 0) return true;
    return false;
}

bool solve() {
    for (int i = 0; i < n; i++) {
	for (int j = i + 1; j < n; j++) {
	    int t = gcd(x[i], x[j]);
	    if (judge(t, y[i] - z[j], z[i] - y[j]))
		return true;
	}
    }
    return false;
}

int main() {
    while (~scanf("%d", &n)) {
	for (int i = 0; i < n; i++)
	    scanf("%d%d%d", &x[i], &y[i], &z[i]);
	if (solve())
	    printf("Cannot Take off\n");
	else
	    printf("Can Take off\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值