zoukankan      html  css  js  c++  java
  • CODE FESTIVAL 2016 Grand Final【杂题】

    A 1D Matching

    贪心从左往右匹配,只要保证每个坐标的贡献系数正确即可。

    时间复杂度 (O(n))

    #include<bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long LL;
    const int N = 200003, mod = 1e9 + 7;
    int read(){
    	int ch = getchar(), x = 0; bool f = false;
    	for(;ch < '0' || ch > '9';ch = getchar()) f |= ch == '-';
    	for(;ch >= '0' && ch <= '9';ch = getchar()) x = x * 10 + ch - '0'; 
    	return f ? -x : x;
    }
    int n, now, ans = 1;
    pair<int, int> a[N];
    int main(){
    	n = read();
    	for(int i = 0;i < (n<<1);++ i)
    		a[i] = MP(read(), i<n);
    	sort(a, a+(n<<1));
    	for(int i = 0;i < (n<<1);++ i)
    		if(a[i].se){
    			if(now < 0) ans = LL(-now) * ans % mod;
    			++ now;
    		} else {
    			if(now > 0) ans = LL(now) * ans % mod;
    			-- now;
    		}
    	printf("%d
    ", ans);
    }
    

    B Inscribed Bicycle

    数学题,谔谔谔谔。

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int x0, y0, x1, y1, x2, y2;
    	scanf("%d%d%d%d%d%d", &x0, &y0, &x1, &y1, &x2, &y2);
    	x1 -= x0; y1 -= y0; x2 -= x0; y2 -= y0;
    	int S = abs(x1*y2-x2*y1);
    	double a[3] = {sqrt(x1*x1+y1*y1), sqrt(x2*x2+y2*y2), sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))};
    	sort(a, a + 3);
    	double r = S / (a[0] + a[1] + a[2]);
    	printf("%.12lf
    ", a[2] / (2 + a[2] / r));
    }
    

    C Cheating Nim

    实际上题目就是要求选择一些 (a_ioplus(a_i-1)) 使得异或起来等于给定的数 (igoplus_{i=1}^n a_i)

    然后发现 (xoplus(x-1)=2 ext{lowbit}(x)-1) 一定是 (2^k-1) 的形式。所以异或方案是唯一的。

    #include<bits/stdc++.h>
    using namespace std;
    int n, x, sum, ans;
    bool vis[30];
    int main(){
    	scanf("%d", &n);
    	for(int i = 1;i <= n;++ i){
    		scanf("%d", &x);
    		sum ^= x;
    		vis[__builtin_ctz(x)] = true;
    	}
    	for(int i = 29;~i;-- i)
    		if(sum>>i&1){
    			if(!vis[i]) return puts("-1"), 0;
    			sum ^= (1<<i+1)-1; ++ ans;
    		}
    	printf("%d
    ", ans);
    }
    

    D Dice Game

    假设 Petr 以 (x) 的概率选红骰子,(1-x) 的概率选蓝骰子。那么 tourist 获胜的概率应当是 (sum_{i=1}^6max{p_ix,q_i(1-x)}),那么 Petr 会取使该值最小的 (x)

    那为什么 tourist 一定能选中 (max) 呢,实际上因为博弈论基本定理,只要收益函数对双方分别满足一定的凹凸性,双方就会不约而同地选中均衡点。

    #include<bits/stdc++.h>
    using namespace std;
    typedef double db;
    const db eps = 1e-12;
    db p[6], q[6];
    db f(db x){
    	db r = 0;
    	for(int i = 0;i < 6;++ i)
    		r += max(p[i]*x, q[i]*(1-x));
    	return r;
    }
    int main(){
    	for(int i = 0;i < 6;++ i) scanf("%lf", p+i), p[i] /= 100;
    	for(int i = 0;i < 6;++ i) scanf("%lf", q+i), q[i] /= 100;
    	db l = 0, r = 1;
    	while(r - l > eps){
    		db lm = l+(r-l)/3, rm = r-(r-l)/3;
    		if(f(lm) < f(rm)) r = rm;
    		else l = lm;
    	}
    	printf("%.12f", f(l));
    }
    

    E Water Distribution

    一言不合就建图,当 (s ightarrow t) 有运水的时候连边 ((s,t))

    显然每个连通块之间不互相影响。所以对每个连通块分别考虑。

    (n,A,B) 分别表示当前连通块的点数、每个点的水量之和、每条边的代价之和。

    然后就可以发现只要 dfs 一遍生成树就可以使最小值 (gefrac{A-B}n),然后取错不优,所以直接按这个值算就行。

    对每个点集跑最小生成树之后就可以子集 dp 了,时间复杂度 (O(3^n+2^nn^2))

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef double db;
    const int N = 15, M = 105;
    template<typename T>
    bool chmax(T &a, const T &b){if(a < b) return a = b, 1; return 0;}
    int n, m, k, lim, fa[N], x[N], y[N], a[N];
    db f[1<<N];
    struct Edge {
    	int u, v; db w;
    	bool operator < (const Edge &o) const {
    		return w < o.w; 
    	}
    } e[M];
    int getf(int x){return x == fa[x] ? x : fa[x] = getf(fa[x]);}
    db dis(int a, int b){
    	return sqrt(LL(x[a]-x[b])*(x[a]-x[b])+LL(y[a]-y[b])*(y[a]-y[b]));
    }
    int main(){
    	scanf("%d", &n); lim = 1<<n;
    	for(int i = 0;i < n;++ i)
    		scanf("%d%d%d", x+i, y+i, a+i);
    	for(int S = 1;S < lim;++ S){
    		m = k = 0;
    		for(int i = 0;i < n;++ i) if(S>>i&1){
    			f[S] += a[i];
    			fa[i] = i;
    			++ k;
    			for(int j = i+1;j < n;++ j) if(S>>j&1){
    				e[m].u = i; e[m].v = j;
    				e[m++].w = dis(i, j);
    			}
    		}
    		sort(e, e + m);
    		for(int i = 0, j = 1;i < m && j < k;++ i){
    			int u = getf(e[i].u), v = getf(e[i].v);
    			if(u != v){f[S] -= e[i].w; fa[u] = v; ++ j;}
    		}
    		f[S] /= k;
    	}
    	for(int S = 1;S < lim;++ S)
    		for(int T = S&S-1;T;T = S&T-1)
    			chmax(f[S], min(f[T], f[S^T]));
    	printf("%.9lf
    ", f[lim-1]);
    }
    

    G FESTIVAL

    FESTIVA(LLL...LLL)FESTIVA(LLL...LLL)....

    设这些组分别有 (c_0,c_1,cdots) 个 L,则对应答案为 (sum c_iinom{i+7}7)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 512;
    LL k, f[N]; int c[N], mx;
    int main(){
    	scanf("%lld", &k);
    	f[0] = 1;
    	for(int i = 1;i < N;++ i) f[i] = f[i-1] * (i+7) / i;
    	for(int i = N-1;~i;-- i)
    		if(k >= f[i]){
    			c[i] = k / f[i];
    			if(!mx) mx = i;
    			k %= f[i];
    		}
    	for(int i = 0;i <= mx;++ i){
    		printf("FESTIVA");
    		for(int j = 0;j < c[i];++ j)
    			putchar('L');
    	}
    }
    
  • 相关阅读:
    装饰器 转载自 http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html
    no_merge hint
    优化实例- not use hash to avoid temp space issue
    明日计划
    优化实例- not in 和 not exists
    insert into varchar2(8000)
    图像的批处理
    图像数据类型及颜色空间转换
    图像的读取,显示与保存(基于skimage模块)
    图像直方图
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/14825404.html
Copyright © 2011-2022 走看看