Educational Codeforces Round 108 (Rated for Div. 2) (ABD)

A:Red and Blue Beans
题目大意:
有r个红豆和b个蓝豆,要把这些豆子装到几个袋子里,要求每个袋子至少有一个红豆并且至少有一个蓝豆,并且每个袋子的红豆数量和蓝豆数量的差要小于等于d,问你是否能分配这写豆子。
(只想说比赛的头不对劲,要不然为什么会wa四发)
思路:
假设r>b,则判断(r-b)/b是否小于等于d,是则YES,否则NO。因为至多有b个袋子,多于b个就不符合题目条件。r-b之后就相当于去除了蓝豆,只剩下了红豆,现在问题就转化为红豆在每个袋子的个数是否小于d。那么除以b就好啦。
注意要用double类型
代码:

#include<stdio.h>
#define ll long long 

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		ll r,b,d;
		scanf("%lld%lld%lld",&r,&b,&d);
		if(r>=b)
		{
			if(((double)(r-b)/b)<=d) printf("YES\n");
			else
			{
				printf("NO\n");
			}
		}
		else if(b>r)
		{
			if(((double)(b-r)/r)<=d) printf("YES\n");
			else
			{
				printf("NO\n");
			}
		}
	}
	return 0;
}

B.The Cake Is a Lie
题目大意:
问从(1,1)到(n,m)花费是否等于k。
且只能相邻的点移动,并且(x,y)到(x,y+1)花费x,从(x,y)到(x+1,y)花费y。
花费正好为k就输出YES,否则输出NO。
(卡完A题后心态有点崩,看到B题后五六分钟代码打完剩下时间在怀疑自己是不是想简单了,,,一直在犹豫要不要交)
然后就AC了。
思路:
结论是(m-1)+(n-1)x m,即 n x m-1。
下面是个例子
在这里插入图片描述
假如是从(1,1)走到(3,4),从边缘路走(1,1)->(1,4)->(3,4),分别需要3和8步。如果从中间任意条路走,可以发现,这些路是可以进行平移到相应的边缘路,而相应的花费是可以相互转换,比如按下面图中黑框框走
在这里插入图片描述
可以将花费为2的路转换为花费为4的路,相应的,将花费为3的路转化为花费为1的路。此时总花费为11.
可以发现,无论怎么走,花费都是一样的,这时计算边缘路总花费就为上面的结论。
代码:

#include<stdio.h>
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m,k;
		scanf("%d%d%d",&n,&m,&k);
		long long int x=(m-1)+(n-1)*m;
		if(x==k)
		{
			printf("YES\n");
		}
		else
		{
			printf("NO\n");
		}
	}
	return 0;
}

(D留个坑后几天就写,看博客时候看到了一个不错的写法觉得超级棒!诶嘿有点高兴)
今日填坑:
D. Maximum Sum of Products
题目大意:有两个长度为n的数组a,b。其中a可以进行子序列翻转。问下列式子的最大值是多少。
在这里插入图片描述
思路:
d[ l ][ r ]为翻转这段区间后得到的价值,dfs进行递归
然后用d[l][r]进行存储。
代码:

#include<stdio.h>
#include<string.h>
#define ll long long
ll a[5005],b[5005],d[5005][5005];
ll max(ll a,ll b)
{
	return a>b?a:b;	
}
ll dfs(ll l,ll r)
{
	if(l>=r) return 0;
	if(d[l][r]!=-1) return d[l][r];
	d[l][r]=dfs(l+1,r-1)+a[l]*b[r]+a[r]*b[l]-a[l]*b[l]-a[r]*b[r];
	return d[l][r];
}
int main()
{
	int n;
	ll sum=0,ans=0;
	scanf("%d",&n);
	memset(d,-1,sizeof(d));
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&b[i]);
		sum+=a[i]*b[i];
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			ans=max(ans,dfs(i,j));
		}
	}
	printf("%lld\n",ans+sum);
	return 0;
}

填坑结束(~)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值