Codeforces Round #775 CF1649 ABCD

1649A - Game(英语题)

不能走0,最小跳跃长度

题目描述很微妙,注意只能跳一次!我开始以为是遇到连续 0 0 0才跳,后来感谢EM-LGH大神,才让我悟到了正确题意。

1649B - Game of Ball Passing(贪心)

传球游戏,最小轮数

很容易想到贪心,从最多的人开始,传给现在最多那个人。

这个贪心转化为代码实现,就是找到最大的那个人的球数mx,统计其他人的球数sum,答案是 max ⁡ ( m x − s u m , 1 ) \max(mx-sum,1) max(mxsum,1)

1649C - Weird Sum(dp)

一维坐标,一系列点,问所有任意两点距离和

绕弯了。我是去算每一段都出现了多少次。答案就是 ∑ i = 1 n − 1 c [ i ] ∗ d [ i ] \sum_{i=1}^{n-1} c[i]*d[i] i=1n1c[i]d[i],c[i]是出现次数,观察推公式不难算出,d[i]就是相邻两点距离。推c[i]有点麻烦。

再次感谢MG_LGH,提供了另一个“顺序思路”。从左往右for一遍,对于每个i我们考虑对前面的贡献。显然为 s [ i ] = s [ i − 1 ] + i ∗ d [ i ] s[i]=s[i-1]+i*d[i] s[i]=s[i1]+id[i],答案为 ∑ s [ i ] \sum s[i] s[i]

我的数学方法代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;

int n,m;
vector<int> heng[N],shu[N];

ll a[N],b[N];
ll calc(vector<int> x)
{
	if(x.size()<=1) return 0;
	ll res=0,ji=0,it=x.size()-1;
	sort(x.begin(),x.end());
	for(int i=1;i<=it;i++) a[i]=x[i]-x[i-1];
	
	int mid=(it+1)/2;
	b[mid]=(1ll+mid)*mid/2;//debug 1ll
	for(int i=mid-1,j=1;i>=1;i--)
	{
		b[i]=b[i+1]-j;
		j++;
	}
	for(int i=1;i<=mid;i++) 
		res+=b[i]*a[i],ji+=a[i]*i;
	for(int i=it,j=1;i>mid;i--,j++) //debug for(int i=n,j=1;i>mid;i--,j++)
		res+=b[j]*a[i],ji+=a[i]*j;
	
	res*=2;
	return it&1?res-ji:res;
}

int main()
{
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> n >> m;
	int mc=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			int c;cin >> c;
			mc=max(mc,c);//debug mc
			heng[c].push_back(i);
			shu[c].push_back(j);
		}
	ll ans=0;
	for(int i=1;i<=mc;i++) ans=ans+calc(heng[i])+calc(shu[i]);
//	for(int i=1;i<=mc;i++) cout << calc(heng[i]) << ' ' << calc(shu[i]) << endl;
	cout << ans << endl;
	return 0;
}

1649D - Integral Array(构造)

对于x,y在数列中,且KaTeX parse error: Undefined control sequence: \g at position 3: x \̲g̲ ̲e y ,则 ⌊ x y ⌋ \left \lfloor \frac{x}{y} \right \rfloor yx也在数列中。YES/NO?

题目给出了一个乍一看不知道怎么用的条件, ∑ c ≤ 1 0 6 \sum c \le 10^6 c106。经MG^LGH指点后我大彻大悟,那意思就是可以 O ( C ∗ . . . ) O(C*...) O(C...)来做。因为是判断题,于是试图构造不合理现象。

对于 ⌊ x y ⌋ = k \left \lfloor \frac{x}{y} \right \rfloor = k yx=k,枚举k,对于不存在数列中的k(不合理开始)枚举y,进而可以推算出一个x的区间。判断这个区间内有无x存在,如果有,NO,结束程序。

其中y只需枚举 c k \frac{c}{k} kc次,总计是 ∑ i = 1 n 1 i ≈ ln ⁡ n \sum _{i=1}^{n}\frac{1}{i} \approx\ln n i=1ni1lnn次。故时间复杂度 O ( C ln ⁡ C ) O(C\ln C) O(ClnC)

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;

int n,c;
int s[N],a[N];

int main()
{
	ios::sync_with_stdio(false);cin.tie(0);
	int Case;cin>>Case;
	while(Case--)
	{
		int mx=0;
		cin >> n >> c;
		for(int i=1;i<=c;i++) s[i]=0;
		for(int i=1;i<=n;i++)
		{
			cin >> a[i];
			s[a[i]]++;
			mx=max(mx,a[i]);
		}
		for(int i=1;i<=mx;i++) s[i]+=s[i-1];
		
		for(int i=1;i<=mx;i++) if(!(s[i]-s[i-1]))
		{
			for(int j=1;i*j<=mx;j++) if(s[j]-s[j-1])
			{
				int L=i*j,R=min(mx,j*(i+1)-1);
				if(s[R]-s[L-1]) goto fail;
			}
		}
		
		cout << "YES\n";
		continue;
fail:	cout << "NO\n";
	}
}

1649E - Tyler and Strings

1649F - Serious Business

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值