2013 通化邀请赛

A:求平均数,水题,注意输出的格式。

D:从后往前做并查集,并记录集合个数即可

E:数论,先把L / G 分解质因子,然后这些质因子要分给三个数,就是A(3,2)每个因子的个数再相乘

G:暴力dfs剪枝。

H:记忆化搜索,dp[20][20][20][20][2]的状态,前4维的状态记录牌取的情况,最后一维记录是谁取的。

A:

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

int t;
double sum;
int main() {
    scanf("%d", &t);
    while (t--) {
	sum = 0;
	double num;
	for (int i = 0; i < 12; i++) {
	    scanf("%lf", &num);
	    sum += num;
	}
	sum /= 12;
	printf("$%d", (int)sum);
	sum = (sum - floor(sum));
	int s = int(sum * 100 + 0.5);
	if (s != 0) {
	    printf(".");
	    printf("%d", s / 10);
	    s %= 10;
	    if (s != 0)
		printf("%d", s);
	}
	printf("\n");
    }
    return 0;
}


D:

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

const int N = 10005;
const int M = 100005;

int n, m, a[M], b[M], parent[N], ans[M];

void init() {
    for (int i = 0; i < n; i++)
	parent[i] = i;
}

int find(int x) {
    if (x == parent[x]) return x;
    return parent[x] = find(parent[x]);
}

int main() {
    while (~scanf("%d%d", &n, &m)) {
	init();
	for (int i = 0; i < m; i++)
	    scanf("%d%d", &a[i], &b[i]);
	int sum = n;
	for (int i = m - 1; i >= 0; i--) {
	    ans[i] = sum;
	    int pa = find(a[i]);
	    int pb = find(b[i]);
	    if (pa != pb) {
		parent[pa] = pb;
		sum--;
	    }
	}
	for (int i = 0; i < m; i++)
	    printf("%d\n", ans[i]);
    }
    return 0;
}

E:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
using namespace std;

int t;
long long n, m;

long long solve(long long n, long long m) {
    if (m % n) return 0;
    long long num = m / n;
    long long Max = sqrt(num);
    long long ans = 1;
    for (int i = 2; i <= Max && i <= num; i++) {
	if (num % i == 0) {
	    long long count = 0;
	    while (num % i == 0) {
		count++;
		num /= i;
	    }
	    ans *=  (6 * count);
	}
    }
    if (num > 1)
	ans *= 6;
    return ans;
}

int main() {
    scanf("%d", &t);
    while (t--) {
	cin >> n >> m;
	cout << solve(n, m) << endl;
    }
    return 0;
}

H:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 25;
int t, n, num1[N], num2[N], dp[N][N][N][N][2];

int dfs(int s1, int e1, int s2, int e2, int who) {
    int &ans = dp[s1][e1][s2][e2][who];
    if (ans != -1) return ans;
    if (s1 > e1 && s2 > e2) return ans = 0;
    if (who == 1) {
	ans = 0;
	if (s1 <= e1) {
	    ans = max(ans, dfs(s1 + 1, e1, s2, e2, (!who)) + who * num1[s1]);
	    ans = max(ans, dfs(s1, e1 - 1, s2, e2, (!who)) + who * num1[e1]);
	}
	if (s2 <= e2) {
	    ans = max(ans, dfs(s1, e1, s2 + 1, e2, (!who)) + who * num2[s2]);
	    ans = max(ans, dfs(s1, e1, s2, e2 - 1, (!who)) + who * num2[e2]);
	}
    }
    else {
	ans = INF;
	if (s1 <= e1) {
	    ans = min(ans, dfs(s1 + 1, e1, s2, e2, (!who)) + who * num1[s1]);
	    ans = min(ans, dfs(s1, e1 - 1, s2, e2, (!who)) + who * num1[e1]);
	}
	if (s2 <= e2) {
	    ans = min(ans, dfs(s1, e1, s2 + 1, e2, (!who)) + who * num2[s2]);
	    ans = min(ans, dfs(s1, e1, s2, e2 - 1, (!who)) + who * num2[e2]);
	}
    }
    return ans;
}

int main() {
    scanf("%d", &t);
    while (t--) {
	memset(dp, -1, sizeof(dp));
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	    scanf("%d", &num1[i]);
	for (int i = 1; i <= n; i++)
	    scanf("%d", &num2[i]);
	printf("%d\n", dfs(1, n, 1, n, 1));
    }
    return 0;
}

G:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int N = 10;
int n, m, q, x, y, g[N][N], s[32], sn, ans, tmp;

int bitcount(int x) {
    if (x == 0) return 0;
    return bitcount(x / 2) + (x&1);
}

void table() {
    sn = 0;
    for (int i = 0; i < 32;i ++) {
	if (bitcount(i) <= 3) 
	    s[sn++] = i;
    }
}

bool judge(int d, int s) {
    for (int i = 0; i < m; i++) {
	if (g[d][i] == 1 && (s&(1<<i)))
	    return false;
    }
    return true;
}

bool checkup(int x, int y) {
    int flag = 0;
    for (int i = x - 1; i >= 0; i--) {
	if (flag&& g[i][y] == 2) return false;
	else if (flag && g[i][y] == 1) return true;
	if (g[i][y]) flag = 1;
    }
    return true;
}

bool checklf(int x, int y) {
    int flag = 0;
    for (int i = y - 1; i >= 0; i--) {
	if (flag && g[x][i] == 2) return false;
	else if (flag && g[x][i] == 1) return true;
	if (g[x][i]) flag = 1;
    }
    return true;
}

bool check(int d) {
    for (int i = 0; i < m; i++) {
	if (g[d][i] == 2) {
	    if (!checkup(d, i))
		return false;
	    if (!checklf(d, i))
		return false;
	}
    }
    return true;
}

void dfs(int d, int num) {
    if (n == 5) {
	if (num + (n - d) * 3 <= ans) return;
    }
    else {
	if (num + (n - d) * 2 <= ans) return;
    }
    if (d == n) {
	ans = max(ans, num);
	return;
    }
    for (int i = 0; i < sn; i++) {
	if (s[i] > tmp) continue;
	if (judge(d, s[i])) {
	    for (int j = 0; j < m; j++) {
		if (s[i]&(1<<j))
		    g[d][j] = 2;
	    }
	    if (check(d)) {
		dfs(d + 1, num + bitcount(s[i]));
	    }
	    for (int j = 0; j < m; j++) {
		if (s[i]&(1<<j))
		    g[d][j] = 0;
	    }
	}
    }
}

int main() {
    table();
    while (~scanf("%d%d%d", &n, &m, &q)) {
	ans = 0; tmp = (1<<m) - 1;
	memset(g, 0, sizeof(g));
	while (q--) {
	    scanf("%d%d", &x, &y);
	    g[x][y] = 1;
	}
	dfs(0, 0);
	printf("%d\n", ans);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值