Educational Codeforces Round 122 (Div. 2)(A~D)(E未补)

(咕咕咕了挺久了,感觉还是要写下)

A. Div. 7 (思维+数学)

可以发现对于任意一个数字,我们最多需要修改一位数。

我们可以假设k=n%7,只需修改个位数字p -> p-k/ p->p-k+7(一定有一个符合)

#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
using namespace std;
ll n;

void sol()
{
	ll ans=n%7,k=n%10;
	if (k-ans>=0)
		printf("%lld\n",n-ans);
	else
		printf("%lld\n",n+7-ans);
}

int main()
{
	ll tt;
	scanf("%lld",&tt);
	while (tt--)
	{
		scanf("%lld",&n);
		sol();
		
	}
	return 0;
}

B. Minority(贪心+思维)

我们可以设a为0的个数,b为1的个数

如果a!=b,ans=min(a,b)

如果a=b,我们可以删除首字符或尾字符,ans=a-1=b-1

#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
using namespace std;
ll a[Ma];

int main()
{
	ll tt;
	scanf("%lld",&tt);
	while (tt--)
	{
		string s;
		cin>>s;
		ll x=0,y=0;
		for (ll i=0;i<s.size();i++)
			if (s[i]=='1')
				x++;
			else
				y++;
		if (x==y)
			printf("%lld\n",x-1);
		else
			printf("%lld\n",min(x,y));
	}
	return 0;
}

C. Kill the Monster(暴力/数论)

当时看到这题,心想这不是数论裸板子么,写了10分钟一看过了一坨人,再看了下k<=2e5,😭;

方法一:O(\sqrt(hc+k))枚举回合数(经典数论莫反),显然容易炸

方法二:可以发现升级一定是用满的(毕竟不加白不加),因此枚举情况取最大即可。

#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
using namespace std;
int main()
{
	ll tt;
	scanf("%lld",&tt);
	while (tt--)
	{
		ll hc,dc,hm,dm;
		scanf("%lld %lld",&hc,&dc);
		scanf("%lld %lld",&hm,&dm);
		ll k,w,a;
		scanf("%lld%lld%lld",&k,&w,&a);
		ll flag=0;
		for (ll i=0;i<=k;i++)
		{
			ll x=(hc+a*i-1)/dm,y=(hm-1)/(dc+w*(k-i));
			if (x>=y)
				flag=1;
		}
		if (flag)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}

D. Make Them Equal(打表+dp优化)

首先我们可以用o(n^2)打表得出第i个数字需要花费ask[a[i]]次操作,用背包实现O(n*k),显然这会TLE(博主过于傻逼认为CFYYDS,1s1e9不是梦,然后TLE12了)。然后我们发现上面打表后每个数的操作次数最多为12次,因此可以优化到O(12*n^2),这就可以ACrua。

#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
using namespace std;
ll dp[Ma];
ll ask[Ma];
ll a[Ma],b[Ma];
ll n,k;
ll ma=0;

void sol()
{
	if (n*ma<=k)
	{
		ll ans=0;
		for (ll i=1;i<=n;i++)
			ans+=b[i];
		printf("%lld\n",ans);
		return;
	}
	for (ll i=1;i<=n;i++)
	{
		for (ll j=k;j>=ask[a[i]];j--)
			dp[j]=max(dp[j],dp[j-ask[a[i]]]+b[i]);
	}
	printf("%lld\n",dp[k]);
	return;
}

int main()
{
	memset(ask,0x3f,sizeof(ask));
	ask[1]=0;
	for (ll i=1;i<=1000;i++)
		for (ll j=i;j>=1&&i+i/j<=1000;j--)
			ask[i+i/j]=min(ask[i+i/j],ask[i]+1);
	for (ll i=1;i<=1000;i++)
		ma=max(ma,ask[i]);
	cout<<ma<<endl;
	ll tt;
	scanf("%lld",&tt);
	while (tt--)
	{
		scanf("%lld%lld",&n,&k);
		memset(dp,0,sizeof(dp));
		for (ll i=1;i<=n;i++)
			scanf("%lld",&a[i]);
		for (ll i=1;i<=n;i++)
			scanf("%lld",&b[i]);
		sol();
	}
	return 0;
}

 最近场数比较多,加上开学事也多,而且感觉E我也不是很擅长,就看心情随缘补rua

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值