Codeforces Global Round 2

A:正反跑一遍就能求出最长不同数距离

#include<bits/stdc++.h>
using namespace std;
const int M =300000+100;
int a[M];
int dis[M];
int vis[M];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	int ma=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i]!=a[n])
		{
			ma=max(ma,n-i);
			break;
		}
		
	}
	for(int i=n;i>=1;i--)
	{
		if(a[i]!=a[1])
		{
			ma=max(ma,i-1);
			break;
		}
	}
	printf("%d\n",ma);
	return 0;
}

B:

枚举前k个,判断前k个能否放进冰箱里。

最大的肯定单放,然后次大的于最大的放一层,次次大的单放…………以此类推

#include<bits/stdc++.h>
using namespace std;
const int M =100000+100;
int aa[M];
int a[M];
int b[M];
int h;
bool check(int n)
{
	for(int i=1;i<=n;i++)
		a[i]=aa[i];
	int b1=0;
	sort(a+1,a+1+n);
	int cnt=0,now=0,nowv=0;
	for(int i=n;i>=1;i--)
	{
		if(now<cnt)
		{
			now++;
			continue;
		}
		b1+=a[i];
		if(b1>h)
		{
			now++;
		//	printf("%d  %d  cnt=%d\n",now,a[i],cnt);
			if(cnt<now)
			{
				return false;
			}
			b1-=a[i];
		}
		else
		{
			b[++cnt]=a[i];
		}
	}
	return true;
}
int main()
{
	int nn;
	cin>>nn>>h;
	int b1=0,b2=0;
	for(int i=1;i<=nn;i++)
	{
		scanf("%d",&aa[i]);
	}
	int l=1,r=nn;
	int pos=0;
	for(int i=1;i<=r;i++)
	{
		if(!check(i))
		{
			printf("%d\n",i-1);
			return 0;
		}
	}
/*	while(l<=r)
	{
		int mid=(l+r)/2;
	//	printf("%d ------ %d\n",l,r);
		if(check(mid))
		{
			l=mid+1;
			pos=mid;
		}
		else
			r=mid-1;
	}*/
	printf("%d\n",r);
	return 0;
}

C:、行列都是偶数就行。

#include<bits/stdc++.h>
using namespace std;
const int M =500+100;
int a[M][M];
int b[M][M];
int c[M][M];
int vis[M];
int main()
{
	int n,m;cin>>n>>m;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
		scanf("%d",&a[i][j]);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		scanf("%d",&b[i][j]);
		if(a[i][j]!=b[i][j])c[i][j]=1;
	//	printf("%d",c[i][j]);
	//	if(j==m)
	//	puts("");
	}
	bool f=true;
	int h=0,l=0;
	for(int i=1;i<=m;i++)
	{
		l=0;
		for(int j=1;j<=n;j++)
		{
			l+=c[j][i];
		}
		if(l%2==1)
		{
			f=false;
			break;
		}
	}
	for(int i=1;i<=n;i++)
	{
		l=0;
		for(int j=1;j<=m;j++)
		{
			l+=c[i][j];
		}
		if(l%2==1)
		{
			f=false;
			break;
		}
	}
	if(f)
	puts("Yes");
	else
	puts("No");
	/*for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		{
			vis[i]=1;
			for(int j=i;j<=n;j++)
			{
				if(!vis[j])
				{
					vis[j]=1;
					for(int k=1;k<=m;k++)
					{
						if(c[i][k]!=c[j][k])
					}
				}
			}
		}
	}*/
	return 0;
}

D;

根据样例解释的表,我们观察可以发现。

如果把s【i】进行排序,那每一行的权值(除了第一行)都是s[i]-s[i-1]于len的最小值

由此我们排序  去重,出去第一个 对2--》n的数进行查分处理,然后二分找到大于len的数,最后求解即可

#include<bits/stdc++.h>
using namespace std;
const int M = 100000+100;
long long a[M],s[M],c[M];
int main()
{
	int n;
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	cin>>n;
  	for(int i=1;i<=n;i++)
  		cin>>s[i];
	sort(s+1,s+1+n);
	n=unique(s+1,s+1+n)-(s+1);
	for(int i=1;i<n;i++)
		c[i]=s[i+1]-s[i];
	sort(c+1,c+n);
	for(int i=1;i<n;i++)
		a[i]=c[i]+a[i-1];
	long long q,l,r;
	cin>>q;
	for(int i=1;i<=q;i++)
	{
		cin>>l>>r;
		long long len=(r-l+1);
		long long ff=lower_bound(c+1,c+n,len)-c;
//		cout<<endl<<ff<<"---ff"<<endl;
	//	cout<<a[ff-1]<<"----a[ff-1]"<<endl;
		if(i==1)                                                                           
		cout<<a[ff-1]+len*(n-ff+1);
		else
		cout<<" "<<a[ff-1]+len*(n-ff+1);
	}
	cout<<endl;
	return 0;
}

E先取3个 再取2大一小,不知道对不对明天交试试

E题我的处理比较好理解,可能代码多点。。

边读边处理,从最小的边开始,

要么是当前木棍选2个+一个之前剩的木棍,要么是三个当前木棍。很明显,最好是先利用完之前剩的木棍,再进行后面木棍的操作。

然后就是简单的模拟就行了。

#include<bits/stdc++.h>
using namespace std;
int n;
long long t,rest,sum;
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
	int n,x;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>x;
		int w=x/2;
		if(w>rest)//当前木棍选2个加上之前剩下的一个木棍的情况
		{
			x-=rest*2;
			sum+=rest;
			rest=x;
		}
		else
		{	
			rest=rest-w+x%2;
			sum+=w;
			x=x%2;
		}
		if(x>=3)//选三个当前木棍
		{
			sum+=x/3;
			rest=x%3;
		}
	//	printf("rest=%d  sum=%d  i = %d x = %d\n",rest,sum,i,x);
	}
	cout<<sum<<endl;
	return 0;
}
/*
*这种就是只考虑剩下的木棍,最后用总和减去剩下的木棍
 *
*/

#include<cstdio>
using namespace std;
int n;
long long t,rst,sum;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&t);
		sum+=t;
		if(t>=2*rst) rst=(t-2*rst)%3;
		else rst=rst-t/2+t%2;
	}
	printf("%lld",(sum-rst)/3);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值