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(mx−sum,1)
1649C - Weird Sum(dp)
一维坐标,一系列点,问所有任意两点距离和
绕弯了。我是去算每一段都出现了多少次。答案就是 ∑ i = 1 n − 1 c [ i ] ∗ d [ i ] \sum_{i=1}^{n-1} c[i]*d[i] ∑i=1n−1c[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[i−1]+i∗d[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 ∑c≤106。经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=1ni1≈lnn次。故时间复杂度 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";
}
}