Codeforces 364

A

  第一题明显统计,注意0和long long(我WA,RE好几次)

/* 
 * Problem: A. Matrix
 * Author: Shun Yao
 */

#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <time.h>

#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#include <bitset>
#include <utility>
#include <iomanip>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>

//using namespace std;

int a, n, b[4444], c[44444];
char s[4444];

int main(/*int argc, char **argv*/) {
    int i, j, x;
    long long ans;
    
    scanf("%d", &a);
    scanf(" %s", s + 1);
    n = strlen(s + 1);
    for (i = 1; i <= n; ++i)
        b[i] = s[i] - '0';
    memset(c, 0, sizeof c);
    ans = 0;
    for (i = 1; i <= n; ++i) {
        x = 0;
        for (j = i; j <= n; ++j) {
            x += b[j];
            ++c[x];
        }
    }
    if (a) {
        for (i = 1; i <= 40000 && i * i <= a; ++i)
            if (a % i == 0 && a / i <= 40000)
                ans += static_cast<long long>(c[i]) * c[a / i] * (i * i == a ? 1 : 2);
    } else
        ans = static_cast<long long>(c[0]) * (n * (n + 1) - c[0]);
    printf("%I64d", ans);
    
    fclose(stdin);
    fclose(stdout);
    return 0;
}

B

  用背包算出每个价值是否出现过,然后贪心即可。

/* 
 * Problem: B. Free Market
 * Author: Shun Yao
 */

#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <time.h>

#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#include <bitset>
#include <utility>
#include <iomanip>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>

//using namespace std;

int n, d, c[55], f[500010];

int main(/*int argc, char **argv*/) {
    int i, j, sum, ans1, ans2;
    
    scanf("%d%d", &n, &d);
    sum = 0;
    for (i = 1; i <= n; ++i) {
        scanf("%d", c + i);
        sum += c[i];
    }
    memset(f, 0, sizeof f);
    f[0] = 1;
    for (i = 1; i <= n; ++i)
        for (j = sum; j >= c[i]; --j)
            f[j] |= f[j - c[i]];
    ans1 = 0;
    ans2 = 0;
    while (ans1 < sum) {
        for (j = ans1 + d <= sum ? ans1 + d : sum; j > ans1; --j)
            if (f[j])
                break;
        if (j <= ans1)
            break;
        ans1 = j;
        ++ans2;
    }
    printf("%d %d", ans1, ans2);
    
    fclose(stdin);
    fclose(stdout);
    return 0;
}

C

  不懂证明,求解释。。。

D

  做法是随机算法(没有想到啊。)

/* 
 * Problem: D. Ghd
 * Author: Shun Yao
 */

#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <time.h>

#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#include <bitset>
#include <utility>
#include <iomanip>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>

//using namespace std;

const int MAXN = 1000010;

int n;
long long a[MAXN], ans;
std::vector<long long> e, v;

long long gcd(long long a, long long b) {
	return !b ? a : gcd(b, a % b);
}

int main(/*int argc, char **argv*/) {
	int i, j, x;
	
//	freopen("D.in", "r", stdin);
//	freopen("D.out", "w", stdout);
	
	scanf("%d", &n);
	for (i = 1; i <= n; ++i)
		scanf("%I64d", a + i);
	srand((unsigned)time(0));
	ans = 0;
	while (clock() < 3000L) {
		x = static_cast<long long>(rand()) * rand() % n + 1;
		e.clear();
		v.clear();
		for (i = 1; static_cast<long long>(i) * i <= a[x]; ++i)
			if (a[x] % i == 0) {
				e.push_back(i);
				if (static_cast<long long>(i) * i != a[x])
					e.push_back(a[x] / i);
			}
		std::sort(e.begin(), e.end());
		v.resize(e.size(), 0);
		for (i = 1; i <= n; ++i)
			++v[std::lower_bound(e.begin(), e.end(), gcd(a[x], a[i])) - e.begin()];
		for (i = 0; i < static_cast<int>(e.size()); ++i) {
			for (j = i + 1; j < static_cast<int>(e.size()); ++j)
				if (e[j] % e[i] == 0)
					v[i] += v[j];
			if (v[i] + v[i] >= n)
				ans = std::max(ans, e[i]);
		}
	}
	printf("%I64d", ans);
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}

 E

  二维分治。

/*
 * Problem: E. Empty Rectangles
 * Author: Shun Yao
 */

#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <time.h>

#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#include <bitset>
#include <utility>
#include <iomanip>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>

//using namespace std;

int n, m, k;
char s[2505][2505];
long long a[2505][2505];

inline long long sum(int r1, int c1, int r2, int c2) {
	return a[r2][c2] - a[r1 - 1][c2] - a[r2][c1 - 1] + a[r1 - 1][c1 - 1];
}

long long go(int r1, int c1, int r2, int c2) {
	if (r1 == r2 && c1 == c2)
		return sum(r1, c1, r2, c2) == k;
	if (r2 - r1 > c2 - c1) {
		long long cnt = 0;
		int m = (r1 + r2) >> 1;
		int up[k + 1], dw[k + 1];
		for (int i = c1; i <= c2; i++) {
			for (int x = 0; x <= k; x++)up[x] = m - r1 + 1, dw[x] = r2 - m;
			for (int j = i; j <= c2; j++) {
				for (int x = 0; x <= k; x++) {
					while (up[x] && sum(m - up[x] + 1, i, m, j) > x)
						--up[x];
					while (dw[x] && sum(m + 1, i, m + dw[x], j) > x)
						--dw[x];
				}
				for (int x = 0; x <= k; x++) {
					cnt += (long long)(up[x] - (x ? up[x - 1] : 0)) * (dw[k - x] - (k - x ? dw[k - x - 1] : 0));
				}
			}
		}
		return cnt + go(r1, c1, m, c2) + go(m + 1, c1, r2, c2);
	} else {
		long long cnt = 0;
		int m = (c1 + c2) >> 1;
		int up[k + 1], dw[k + 1];
		for (int i = r1; i <= r2; i++) {
			for (int x = 0; x <= k; x++)up[x] = m - c1 + 1, dw[x] = c2 - m;
			for (int j = i; j <= r2; j++) {
				for (int x = 0; x <= k; x++) {
					while (up[x] && sum(i, m - up[x] + 1, j, m) > x)up[x]--;
					while (dw[x] && sum(i, m + 1, j, m + dw[x]) > x)dw[x]--;
				}
				for (int x = 0; x <= k; x++) {
					cnt += (long long)(up[x] - (x ? up[x - 1] : 0)) * (dw[k - x] - (k - x ? dw[k - x - 1] : 0));
				}
			}
		}
		return cnt + go(r1, c1, r2, m) + go(r1, m + 1, r2, c2);
	}
}

int main() {
	freopen("E.in", "r", stdin);
	freopen("E.out", "w", stdout);
	
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 1; i <= n; i++)scanf("%s", &s[i][1]);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + s[i][j] - '0';
		}
	}
	printf("%I64d", go(1, 1, n, m));
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}

 

posted @ 2014-01-11 21:37  hsuppr  阅读(406)  评论(0编辑  收藏  举报