zoukankan      html  css  js  c++  java
  • Codeforces Round #700 (Div. 2)

    题目链接

    B

    按照monster的攻击力排序

    由于存在同归于尽也算成功 所以我们需要讲攻击力最大的monster放在最后 保证同归于尽的这一次效率最大

    CODE:

    #include<bits/stdc++.h>
    #define M 1008611
    using namespace std;
    int T,n;
    long long A,B;
    bool flag;
    struct Node
    {
    	long long ai,bi,val;
    	friend bool operator <(const Node &a,const Node &b)
    	{return a.ai<b.ai;}
    }e[M];
    long long check(long long x,long long y)
    {return (x%y) ? (x/y)+1:(x/y);}//由于存在同归于尽 所以致死时的那一次攻击也要算上
    int main()
    {
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%lld%lld%d",&A,&B,&n);flag=1;
    		for(int i=1;i<=n;++i) scanf("%lld",&e[i].ai);
    		for(int i=1;i<=n;++i) scanf("%lld",&e[i].bi);
    		sort(e+1,e+n+1);
    		for(int i=1;i<=n;++i)
    		{
    			long long nowx=check(e[i].bi,A)*e[i].ai,nowy=check(B,e[i].ai)*A;
    			if(e[i].bi<=nowy)
    			{
    				if(B<=nowx&&i<n) {flag=0;break;}
    				else B-=nowx;
    			}
    			else {flag=0;break;}
    		}
    		puts(flag ? "YES":"NO");
    	}
    	return 0;
    } 
    

    C

    按照分布的话 可以看作一个波形图 让你寻找一个波谷

    通过排列以及查询次数的范围可以猜出 可以使用二分求解

    CODE:

    #include<bits/stdc++.h>
    #define M 1008611
    using namespace std;
    int n;
    int num[M];
    int main()
    {
    	scanf("%d",&n);
    	num[0]=num[n+1]=1008611;
    	int le=1,ri=n;
    	while(le<ri)
    	{
    		int mid=(le+ri)>>1;
    		printf("? %d\n",mid);fflush(stdout);scanf("%d",&num[mid]);
    		printf("? %d\n",mid+1);fflush(stdout);scanf("%d",&num[mid+1]);
    		if(num[mid]<num[mid+1]) ri=mid;
    		else le=mid+1;
    	}
    	printf("! %d\n",le);
    	return 0;
    } 
    

    D1

    一个贪心题

    我们假设分别维护了两个序列

    当前原序列到了x 将x同两个序列末尾比较

    如果均相同的话 将x放在任一序列末尾均可

    如果只有一个相同一个不同的话 将x放在不相同的序列末尾

    如果均不相同的话 分别查询两个序列末尾的数字在原序列中 后面出现相同的数字哪个更靠前 将x放在这个序列的末尾 从而防止其线段相连

    CODE:

    #include<bits/stdc++.h>
    #define M 1008611
    using namespace std;
    int n,ans;
    int num[M],pos[M],fro[M];
    int ed1,ed2;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i) scanf("%d",&num[i]);
    	for(int i=0;i<=n;++i) pos[i]=n+1;
    	for(int i=1;i<=n;++i) 
    	{
    		if(fro[num[i]]) pos[fro[num[i]]]=i;
    		fro[num[i]]=i;
    	}
    	for(int i=1;i<=n;++i)
    	{
     
    		if(num[i]!=num[ed1]&&num[i]==num[ed2]) {++ans;ed1=i;}
    		else if(num[i]==num[ed1]&&num[i]!=num[ed2]) {++ans;ed2=i;}
    		else if(num[i]!=num[ed1]&&num[i]!=num[ed2]) 
    		{
    			++ans;
    			if(pos[ed1]<pos[ed2]) ed1=i;
    			else ed2=i; 
    		}
    		else if(num[i]==num[ed1]&&num[i]==num[ed2]) ed1=i;
    	}
    	printf("%d\n",ans);
    	return 0;
    } 
    

    D2

    一道贪心题 跟上面的做法很相似

    如果均相同的话 将x放在任一序列末尾均可

    如果只有一个相同一个不同的话 将x放在相同的序列末尾

    如果均不相同的话 分别查询两个序列末尾的数字在原序列中 后面出现相同的数字哪个更靠后 将x放在这个序列的末尾 从而保证其线段相连

    CODE:

    #include<bits/stdc++.h>
    #define M 1008611
    using namespace std;
    int n,ans;
    int num[M],pos[M],fro[M];
    int ed1,ed2;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i) scanf("%d",&num[i]);
    	for(int i=0;i<=n;++i) pos[i]=n+1;
    	for(int i=1;i<=n;++i) 
    	{
    		if(fro[num[i]]) pos[fro[num[i]]]=i;
    		fro[num[i]]=i;
    	}
    //	for(int i=1;i<=n;++i) printf("%d%c",pos[i],(i==n ? '\n':' '));
    	for(int i=1;i<=n;++i)
    	{
    
    		if(num[i]!=num[ed1]&&num[i]==num[ed2]) ed2=i;
    		else if(num[i]==num[ed1]&&num[i]!=num[ed2]) ed1=i;
    		else if(num[i]!=num[ed1]&&num[i]!=num[ed2]) 
    		{
    			++ans;
    			if(pos[ed1]>pos[ed2]) ed1=i;
    			else ed2=i; 
    		}
    		else if(num[i]==num[ed1]&&num[i]==num[ed2]) ed1=i;
    //		printf("now is %d %d\n",ed1,ed2);
    	}
    	printf("%d\n",ans);
    	return 0;
    } 
    
    

    E

    极致构造题

    首先 一看数据范围 L≤R≤\(10^6\) n≤32

    然后这道题也是数的分解 容易让人想到二进制拆分

    我们需要分情况讨论

    1.L=1 R=\(2^k\)

    我们构造k+2个点

    每一个点i(2≤i≤k+2)满足\((1,2^{i-2})\)-continuous

    如何构造?

    我们构造到i的时候 首先建一条边(1-i)=1

    然后对于j(2≤j≤i-1) 构造(j-i)=\(2^{j-2}\)

    这样的话就成为了

    (1,1)->(2,2) 2为中继
    (1,2)->(3,4) 3为中继
    (1,4)->(5,8) 4为中继
    (1,8)->(9,16) 5为中继
    ...
    (1,\(2^{i-3}\))->(\(2^{i-3}+1\),\(2^{i-2}\)) i-1为中继

    2.L=1 R≠\(2^k\)

    首先 二进制拆分 令

    \[R=\sum_{i=0}^k(p_i2^i)(p_i=0,1) \]

    先按照上面的 对于\(2^k\)进行建图

    一定要注意三件事 1.L≤d≤R对应的路径只能有一条 2.不可以存在边权为0的边 3.两点之间只能有一条边

    我们建立第k+3个点 在使用类似于二进制拆分的方法

    假设是R=14 我们先建立(1-k+3)=1

    然后讨论[2,14] 使用二进制拆分

    无标题.png

    使用已经建好的图[2,k+2]中的点同k+3相连

    3.L≠1

    我们建一条边(1,2)=L-1 剩下的按照第2种情况做法就行了

    CODE:

    #include<bits/stdc++.h>
    #define M 1008611
    using namespace std;
    int Le,Ri,cnt;
    int ln[M];
    struct Edge
    {
    	int u,v,w;
    }ans[M];
    void Make_Ans(int now,int knd)
    {
    	int k;
    	if((1<<ln[now])==now)
    	{
    //		printf("cdy\n");
    		k=ln[now]+2;
    		for(int i=2;i<=ln[now]+2;++i)
    		{
    			ans[++cnt]=(Edge){1+knd,i+knd,1};
    			for(int j=2;j<i;++j)
    			ans[++cnt]=(Edge){j+knd,i+knd,(1<<(j-2))};
    		}
    	}
    	else
    	{
    //		printf("wzy\n");
    		k=ln[now]+3;
    		for(int i=2;i<=ln[now]+2;++i)
    		{
    			ans[++cnt]=(Edge){1+knd,i+knd,1};
    			for(int j=2;j<i;++j)
    			ans[++cnt]=(Edge){j+knd,i+knd,(1<<(j-2))};
    		}
    		ans[++cnt]=(Edge){1+knd,k+knd,1};
    		int x=now-1;
    		while(x)
    		{
    			int tmp=x&(-x),tmpx=ln[x&(-x)];
    			ans[++cnt]=(Edge){tmpx+2+knd,k+knd,x-tmp+1};
    			x-=tmp;
    		}	
    	}
    	printf("%d %d\n",k+knd,cnt);
    	for(int i=1;i<=cnt;++i)
    	printf("%d %d %d\n",ans[i].u,ans[i].v,ans[i].w);
    }
    int main()
    {
    	scanf("%d%d",&Le,&Ri);
    	for(int i=1,t=0;i<=1000000;i<<=1,++t) ln[i]=t;
    	for(int i=1;i<=1000000;++i) if(!ln[i]) ln[i]=ln[i-1];
    	puts("YES");
    	if(Le==1) Make_Ans(Ri,0);
    	else
    	{
    		ans[++cnt]=(Edge){1,2,Le-1};
    		Make_Ans(Ri-Le+1,1);
    	}
    	return 0;
    }
    
  • 相关阅读:
    linux tcpdump(转)
    linux ping
    Dalvik VM和JVM 的比较
    Android应用开发基础之八:广播与服务(二)
    Android应用开发基础之七:广播与服务(一)
    Android应用开发基础之五:网络编程(二)
    Android应用开发基础之三:数据存储和界面展现(三)
    Android应用开发基础之二:数据存储和界面展现(二)
    Android应用开发基础之一:数据存储和界面展现(一)
    Android之Fragment 基本介绍(转)
  • 原文地址:https://www.cnblogs.com/tcswuzb/p/14401254.html
Copyright © 2011-2022 走看看