zoukankan      html  css  js  c++  java
  • 重庆2019acm市赛

    A. 狂小P猜密码

    思路

    从题意可知,十个数中有 (1-4)(1) 时是存在方案的,其他情况答案都是 (0)

    已知一多重集,共 (n) 个数,其中 (n_1)(a_1)(n_2)(a_2),...,(n_k)(a_k)。其全排列数为:

    [frac{n!}{n_1!cdot n_2!cdot...cdot n_k!} ]

    可知,当有 (1)(1) 时,答案为 (1)

    当有 (2)(1) 时,可能是一个数出现 (3) 次,另一个数出现 (1) 次;也可能是两个数都出现两次。答案为:

    [2 imesfrac{4!}{3!}+frac{4!}{2!+2!}=8+6=14 ]

    当有 (3)(1) 时,有一个数出现两次,另外两个数出现 (1) 次。答案为:

    [3 imesfrac{4!}{2!}=36 ]

    当有 (4)(1) 时,四个数各出现一次,答案为 (4!=24)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int main(){
    	int num=0;
    	for(int i=1,x;i<=10;i++){
    		scanf("%d",&x);
    		num+=x;
    	}
    	if(num==1) printf("1");
    	else if(num==2) printf("14");
    	else if(num==3) printf("36");
    	else if(num==4) printf("24");
    	else printf("0");
    	return 0;
    }
    

    B. cyy的珍珠奶茶

    思路

    设大圆半径为 (R),小圆半径为 (r),有 (n) 个小圆。

    如果 (n=1)(r=R)

    如果 (n=2)(r=frac{R}{2})

    如果 (ngeq 3),看图

    [a=frac{pi}{n}\r=frac{sin(a)}{1+sin(a)}R ]

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int T;
    double r,n;
    
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		scanf("%lf%lf",&r,&n);
    		if(n==1) {printf("%lf
    ",r);continue;}
    		if(n==2) {printf("%lf
    ",r/2);continue;}
    		double a=3.1415926535/n;
    		double ans=sin(a)/(1+sin(a))*r;
    		printf("%lf
    ",ans);
    	}
    	return 0;
    }
    

    F. JiangYu的机器人

    签到题

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int T,n,x,y,k;
    
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d%d%d",&n,&k,&x,&y);
    		if((y-1)%k==0||(n-y)%k==0||(y-x)%k==0)
    			printf("YES
    ");
    		else printf("NO
    ");
    	}
    	return 0;
    }
    

    G. cyy买奶茶

    思路

    01分数规划+树形Dp

    可以发现题目给了一颗 (n+1) 个节点的树,编号从 (0)(1)

    要求从 (0) 走出,要最后要回到 (0)。可知,走过的每条边累计走两次。

    设第 (i) 个节点点权 (a_i),连接其父节点的边的边权为 (b_i)

    那么本题要求的就是 (frac{sum_{i=1}^{n}x_icdot a_i}{sum_{i=1}^{n}x_icdot 2cdot b_i} (x_i=0 或 1)) 的最大值

    这就是一个典型的01分数规划的问题,解法是用二分,具体可以百度

    然而这个题中每个节点之间是有依赖关系的。

    那么二分的验证就是一个树形Dp,每个节点都要取到最优的价值。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=1e5+10;
    int n,head[MAXN],to[MAXN*2],nxt[MAXN*2],val[MAXN*2],tot,c[MAXN];
     
    void add(int u,int v,int w){
    	to[++tot]=v;val[tot]=w;nxt[tot]=head[u];head[u]=tot;
    }
     
    double sum[MAXN];
    void dfs(int u,int fa,int len,double L){
    	for(int i=head[u];i;i=nxt[i])
    		if(to[i]!=fa)
    			dfs(to[i],u,val[i]*2,L);
    	sum[u]=1.0*c[u]-L*len;
    	for(int i=head[u];i;i=nxt[i])
    		if(to[i]!=fa&&sum[to[i]]>0)
    			sum[u]+=sum[to[i]];
    }
     
     
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&c[i]);
    	for(int i=1,u,v,w;i<=n;i++){
    		scanf("%d%d%d",&u,&v,&w);
    		add(u,v,w);add(v,u,w);
    	}
    	double l=0,r=1e9;
    	while(r-l>1e-8){
    		double mid=(l+r)/2;
    		dfs(0,0,0,mid);
    		if(sum[0]>0) l=mid;
    		else r=mid;
    	}
    	printf("%.6lf
    ",l);
    	return 0;
    }
    

    H. lajiniunai的黑山羊

    思路

    贪心+带权并查集

    首先贪心是很好想到的,将羊群按 (b) 的大小从大到小排序,从前到后依次决定每个羊的 (a) 值,如果当前 (a) 已有羊占用,就 (+1) 再看。当然这样的花费是最少的,但这样慢慢自加肯定会超时。

    用带权并查集可以加速这个自加过程,将连续的用过的数合并到一个集合,如果遇到一个已经用过的数,可以通过并查集直接跳到这个数所在集合的末尾,然后计算花费。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=1e5+10;
    typedef long long LL;
    int T,n,fa[MAXN],siz[MAXN],minv[MAXN];
    map<int,int> mp;
    struct Pair{
    	int a,b;
    }p[MAXN];
    
    bool cmp(Pair x,Pair y){
    	return x.b>y.b;
    }
    
    int get(int x){
    	if(x==fa[x]) return x;
    	int root=get(fa[x]);
    	minv[fa[x]]=min(minv[x],minv[fa[x]]);
    	return fa[x]=root;
    }
    
    void merge(int x,int y){
    	x=get(x),y=get(y);
    	fa[x]=y;
    	minv[y]=min(minv[x],minv[y]);
    	siz[y]+=siz[x];
    }
    
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		mp.clear();
    		scanf("%d",&n);
    		for(int i=1;i<=n;i++)
    			scanf("%d%d",&p[i].a,&p[i].b);
    		for(int i=1;i<=n;i++)
    			fa[i]=i,siz[i]=1;
    		sort(p+1,p+n+1,cmp);
    		LL ans=0;
    		for(int i=1;i<=n;i++){
    			int num;
    			if(!mp[p[i].a]){
    				num=p[i].a;
    			}
    			else{
    				int rt=get(mp[p[i].a]);
    				num=minv[rt]+siz[rt];
    				ans+=1ll*(num-p[i].a)*p[i].b;
    			}
    			mp[num]=i;
    			minv[i]=num;
    			if(mp[num-1]) merge(mp[num-1],i);
    			if(mp[num+1]) merge(mp[num+1],i);
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

    未完待续……

  • 相关阅读:
    nginx中的location匹配规则介绍
    有关博客更新的说明
    nginx配置不同路径下的转发代理
    laravel-admin使editormd支持粘贴截图并自动生成简介
    ERROR [HY000][1822]: Failed to add the foreign key constraint.
    MySQL如何只获得查询结果的前n条数据
    Java常用日期操作
    网络工具_nc
    kali安装工具
    有趣的小东西--打印彩色系统信息
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12083349.html
Copyright © 2011-2022 走看看