ZOJ Monthly, January 2014(2014省份赛练习)

ZOJ Monthly, January 2014(2014省赛练习)

比赛链接

C
每一堆用一个vector保存,排序,询问的时候   枚举小的一堆   然后  在大的一堆里面log(n)找放的位置,然后去算一下答案,

当然你要记录一下做过的询问,如果已经计算过了就没必要计算,直接拿出来就可以了,总体的极限复杂度是O(sqrt(n)*n)

E

n-1个数必然是n*n, n*n-2,........n*n-2*(n-2), 然后剩下的数/2向上取整就是最后一个能得到的最大的数

printf("%d\n", n*n*(n-1)-(n-1)*(n-2)+(n*n-2*n+4)/2);

F

简单搜索

I

队友做的,简单数学题


C:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
using namespace std;
typedef pair<int, int> PII;
#define snuke(it, x) \
	for(__typeof((x).begin())it = (x).begin(); \
			it != (x).end(); it++)
const int N = 100005;
const int M = 100005;
vector <PII > vec[N];
map <PII, int> ans;
int a[N];
int n, m;
int main() {
	int i, j, t;
	while(scanf("%d", &n) == 1) {
		ans.clear();
		for(i = 1; i <= n; i++) {
			vec[i].clear();
			scanf("%d", &a[i]);
			for(j = 0; j < a[i]; j++) {
				scanf("%d", &t);
				vec[i].push_back(make_pair(t, i));
			}
			sort(vec[i].begin(), vec[i].end());
		}
		scanf("%d", &m);
		for(i = 0; i < m; i++) {
			int x, y;
			scanf("%d%d", &x, &y);
			if(vec[x].size() < vec[y].size())
				swap(x, y);
			if(ans.count(make_pair(x, y))) {
				printf("%d\n", ans[make_pair(x, y)]);
				continue;
			}
			int cnt = 0;
			int pre = -1;
			snuke(j, vec[y]) {
				int k = lower_bound(vec[x].begin(), vec[x].end(), *j)-vec[x].begin();
				if(pre == k) continue;
				pre = k;
				if(k != 0)cnt++;
				if(k != vec[x].size()) cnt++;
			}
			ans[make_pair(x, y)] = cnt;
			printf("%d\n", cnt);
		}
	}
	return 0;
}

F:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int a[11];
double ans;
double gao(int a, int b, int c) {
   // printf("a=%d b=%d c=%d\n", a, b, c);
    double p = (a+b+c)*1.0/2;
   // printf("%lf\n", sqrt(p*(p-a)*(p-b)*(p-c)));
    return sqrt(p*(p-a)*(p-b)*(p-c));
}
int b[11];
int c[11];
void dfs(int u) {
    if(u == 6) {
        memset(c, 0, sizeof(c));
        for(int i = 0; i < 6; i++)
            c[b[i]] += a[i];
        sort(c, c+3);
        int cnt[4][4] = {0};
        for(int i = 0; i < 6; i+=2) {
            int x = b[i], y = b[i+1];
            if(x >y) swap(x, y);
            cnt[x][y]++;
        }
        for(int i = 0; i < 3; i++)
            for(int j = i+1; j < 3; j++)
                if(cnt[i][j] >= 2) return;
        if(c[0]+c[1] > c[2] && c[0]&&c[1] && c[2] ) {
            ans = max(ans, gao(c[0], c[1], c[2]));
           // for(int i = 0; i < 6; i++)
          //      printf("%d ", b[i]);
           // puts("");
        }
        return;
    }
    for(int i = 0; i < 3; i++) {
        b[u] = i;
        dfs(u+1);
    }
}
int main() {
    int i, j;
    while(~scanf("%d", &a[0])) {
        for(i = 1; i < 6; i++)
            scanf("%d", &a[i]);
        ans = 0;
        dfs(0);
        printf("%.11f\n", ans);
    }
    return 0;
}