Educational Codeforces Round 125

Educational Codeforces Round 125

没打,只是来补题的。

F 题是 2—SAT,不会(你看这人多菜)。

A.Integer Moves
给定一个点的坐标,从零点开始,每次移动的欧几里得距离均为整数,求移动到给定点的最小次数。

题不难,但容易被样例解释引入歧途(就像我)
很明显,分三种情况。

  • 如果给出点就在零点,就是0
  • 如果给出点到零点的欧几里得距离是整数,就是1
  • 否则为2

对于每次移动,如果只改变 x 或 y 的坐标,移动的欧几里得距离必然是整数。
所以对于每一个点,最多移动两次即可得到。

#include <bits/stdc++.h>
#define dd double
#define int long long
using namespace std;int T,x,y;bool check(dd x,dd y){if(floor(sqrt(x*x+y*y))==sqrt(x*x+y*y))return 1;return 0;}
signed main(){
    cin>>T;while(T--){
        cin>>x>>y;
        if(!x&&!y)puts("0");
        else if(check(x,y))puts("1");
        else puts("2");
    }return 0;
}

B.XY Sequence
给定数字 n,x,y,k,要求从 0 开始,构造一个长度为 n 的序列,满足其中的所有数都小于 k,对于每个数,可以是上一个数加 x,也可以是上一个数减去 y,输出最终序列的最大和。

贪心策略不难想到,如果当前数加上 x 后仍小于 k 就加,否则减。

#include <bits/stdc++.h>
#define int long long
using namespace std;
int x,y,n,T,b,ans,g;
signed main(){
    cin>>T;while(T--){
	cin>>n>>b>>x>>y;ans=0;g=0;
	for(int i=1;i<=n;i++)
	    if(g+x<=b)g+=x,ans+=g;
            else g-=y,ans+=g;
	cout<<ans<<endl;
    }return 0;
}

C.Bracket Sequence Deletion
给定一个括号序列,定义 长度大于等于 2 且回文 或 合法的括号序列可以被删去,每次删去最短的括号序列前缀,输出操作次数和最后剩下的括号数。

还是贪心。

  • 如果当前括号是左括号,则下一个括号无论是什么都满足题目给出的条件,因为是右括号就匹配,是左括号就回文。
  • 如果当点括号是右括号,则下一个出现右括号的位置就是最短前缀的右端点,因为只要出现第二个右括号则当前前缀回文,符合条件,否则只会在后面加左括号,满足加上右括号就回文的条件。
#include <bits/stdc++.h>
#define int long long
using namespace std;const int N=1e6;int n,T,ans1,ans2,f;bool a[N];string s;
signed main(){
    cin>>T;while(T--){
        ans1=ans2=0;cin>>n;cin>>s;for(int i=0;i<n;i++)a[i+1]=(s[i]=='('?0:1);f=0;
	for(int i=1;i<=n;i++){
	    if(f){if(a[i]){f=0;ans1++;ans2=i;}}
	    else{
		if(!a[i]&&i!=n){i++;ans1++;ans2=i;}
		else f=1;
	    }
	}cout<<ans1<<" "<<(n-ans2)<<endl;
    }return 0;
}

D.For Gamers. By Gamers
C 钱币,用于购买 n 种装置打击 m 种怪物。
对于装置 i,有 价格 ci,伤害 di,血量 hi 三个参数。
对于怪物 j,有 伤害 Dj,血量 Hj 两个参数。
求杀死每种怪物且没有装置死亡的最低花费,若无法做到输出 -1。
每次只能用一种装置,但可以多个。

假如说用的是装置 i,数量为 x,要杀死的怪是 j,如果满足题目要求,则 Hjdix<hiDj,将其写成 HjDj<hidix,避免精度问题。
可以想到预处理出对于每个价位,可以产生的最大 hidix 的值,这样做的时间复杂度是 O(C1+C2+C3++CC)=O(Clog2C)
然后二分查找即可。

#include <bits/stdc++.h>
#define int long long
using namespace std;
int R(){
    int x=0,f=0; char ch=getchar();
    while(!isdigit(ch)) f|=(ch==45),ch=getchar();
    while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return f?-x:x;
}const int N=2e6;
int n,m,c,mx[N],f[N],sum,Q,l,r,mid,g;
signed main(){
    n=R();c=R();for(int i=1,C,d,h;i<=n;i++){C=R();d=R();h=R();mx[C]=max(mx[C],d*h);}
    for(int i=1;i<=c;i++){
	sum=1;
	for(int j=i;j<=c;j+=i){
	    f[j]=max(f[j],mx[i]*sum-1);
	    sum++;
	}
    }for(int i=1;i<=c;i++)f[i]=max(f[i],f[i-1]);
    Q=R();for(int i=1,d,h;i<=Q;i++){
	d=R(),h=R();l=1,r=c;g=d*h;
	while(l<=r){
	    mid=(l+r)>>1;
	    if(g>f[mid])l=mid+1;
	    else r=mid-1;
	}
        if(l>c)cout<<-1<<" ";    
        else cout<<l<<" ";
    }
    return 0;
}

E. Star MST
假设有一个 n 个点的无向连通图,每条边的边权均在 [1,k] 之间。
满足其 最小生成树的边权和与节点 1 相连的边的权值和 相等,求方案数。

将题意转化一下:
对于每条边 x>y(x1,y1),满足其边权大于 1>x,1>y 的边权。

很明显用 DP。
假设 fi,j 表示给顶点 1 的 j 条边分配了权值,且其中最大权值为 i 时的方案数。

状态转移方程:fi,k=j<kfi1,jCnj1,kjpow(K+1i,j(kj)+(kj)(kj1)2)
其中 Cnj1,kj 是因为在 nj1 条边中选出 kj 条边,将其权值修改为 i
因为对于 fi1,j,选择了 j 个点向点 1 连边,称之为点集 A,在转移时选择了另外 kj 条边,而 点集 A 连向点集 B 的边点集 B 内部每两点之间的边 的边权都应 i,分别对应 j(kj)(kj)(kj1)2,而因为边权应 i,因此有 K+1i 种取值。

#include <bits/stdc++.h>
#define int long long
using namespace std;
int R(){
    int x=0,f=0; char ch=getchar();
    while(!isdigit(ch)) f|=(ch==45),ch=getchar();
    while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return f?-x:x;
}const int N=601,mod=998244353;
int ksm(int x,int n){int s=1;while(n){if(n&1)s=(s*x)%mod;x=(x*x)%mod;n>>=1;}return s;}
int n,k,c[N][N],f[N][N];
signed main(){
    n=R()-1;k=R();f[k+1][0]=1;
    for(int i=0;i<=300;i++){
	c[i][i]=c[i][0]=1;
	for(int j=1;j<i;j++)
	    c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
    }for(int i=k;i;i--)
	for(int j=0;j<=n;j++)
	    for(int k=0;k+j<=n;k++)
		f[i][j+k]=(f[i][j+k]+f[i+1][j]*ksm(i,j*k+k*(k-1)/2)%mod*c[n-j][k])%mod;
    cout<<f[1][n]<<endl;return 0;
}

别管 F 题了。

posted @   AIskeleton  阅读(62)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示