Codeforces Round #763 (Div. 2)

A

直接 O(1) 用结论搞出来即可,但赛时发现范围很小就直接模拟了(注意到机器人在撞到上面和左面的墙并发生变速之前一定能够清除,只需要模拟撞下面、右面的墙)

int main(){
	int T; cin>>T;
	while(T--){
		int n, m, sx, sy, tx, ty;
		cin>>n>>m>>sx>>sy>>tx>>ty;
		
		int dx=1, dy=1;
		int res=0;
		rep(i,1,420){
			if(sx==tx || sy==ty) break;
			if(sx==n) dx=-dx;
			if(sy==m) dy=-dy;
			sx+=dx, sy+=dy;
			res++;
		}
		cout<<res<<endl;
	}
	return 0;
}

B

对于每个区间,通过枚举断点,肯定能够找到对应的两个子区间(如果断点在端点那就是一个),模拟即可。

const int N=1010;
 
pii q[N];
 
#define x first
#define y second
 
int main(){
	int T; cin>>T;
	while(T--){
		int n; cin>>n;
		set<pii> st;
		
		rep(i,1,n){
			int x, y; read(x), read(y);
			q[i]={x, y};
			st.insert(q[i]);
		}
		
		rep(i,1,n){
			auto [x, y]=q[i];
			if(x==y){
				cout<<x<<' '<<x<<' '<<x<<endl;
				continue;
			}
			rep(j,x,y){
				if(j==x){
					if(st.count({x+1, y})){
						cout<<x<<' '<<y<<' '<<x<<endl;
						break;
					}
				}
				if(j==y){
					if(st.count({x, y-1})){
						cout<<x<<' '<<y<<' '<<y<<endl;
						break;
					}
				}
				if(st.count({x, j-1}) && st.count({j+1, y})){
					cout<<x<<' '<<y<<' '<<j<<endl;
					break;
				}
			}
		}
		// puts("");
	}
	return 0;
}

C

对于这种最大化最小值的问题自然是二分

设现在二分出一个 k,也就是操作后元素都要不小于 k,现在检测其可行性

考虑贪心,为了防止前面的决策影响后面,我们从后面开始决策:我们自然是想要在保证后面大于 k 的前提下尽可能将物品分给前面的,最后我们检查一下决策后是否保证所有元素个数大于等于 k 即可。

const int N=2e5+5;
 
int a[N], b[N];
int n;
 
bool ok(int k){
	rep(i,1,n) b[i]=a[i];
	dwn(i,n,3){
		int h=min(a[i]/3, (b[i]-k)/3);
		b[i-1]+=h, b[i-2]+=2*h;
	}
	rep(i,1,n) if(b[i]<k) return false;
	return true;
}
 
signed main(){
	int T; cin>>T;
	while(T--){
		cin>>n;
		rep(i,1,n) read(a[i]);
		
		int l=1, r=1e10;
		while(l<r){
			int mid=l+r+1>>1;
			if(ok(mid)) l=mid;
			else r=mid-1;
		}		
		cout<<l<<endl;
	}
	return 0;
}

D

赛时我考虑将机器人可以清扫到污渍的点记为关键点,然后将关键点看成图论中的,边权是关键点之间的距离,然后得到一个环,但是写挂了呜呜。

后来看了题解才发现可以写得很简单。

记机器人执行清扫的概率为 p¯

我们设从出发点出发,期望清扫到污渍的步数为 x,记机器人返回出发点且和最初出发时的朝向的步数为 k

设出发点的后继期望清扫到污渍的步数为 y,那么 xy 的关系为:x=w(1+y)

其中,如果出发点为关键点,那么 w=p¯,否则为 1

那么我们有 x=w1(1+w2(1+wk(1+x)))

发现这其实是一个线性方程,可以化成 x=ux+v 的形式,因此可以逆向考虑(考虑得到右式),将 u,v 统计出来,细节见代码。

const int N=1e5+5, mod=1e9+7;

ll fpow(ll x, ll p){
    ll res=1;
    for(; p; p>>=1, x=x*x%mod)
        if(p&1) res=res*x%mod;
    return res%mod;
}

ll inv(ll x){
	return fpow(x, mod-2)%mod;
}

int add(int a, int b){
	return ((a+b)%mod+mod)%mod;
}

int mul(int a, int b){
	return a*b%mod;
}

signed main(){
	int T; cin>>T;
	while(T--){
		int n, m, sx, sy, tx, ty, p;
		cin>>n>>m>>sx>>sy>>tx>>ty>>p;
		p=mul(add(100, -p), inv(100));
		
		int ux=sx, uy=sy;
		int u=1, v=0;
		int dx=-1, dy=-1;
		rep(i,1,4*(n-1)*(m-1)){
			if(ux+dx<1 || ux+dx>n) dx=-dx;
			if(uy+dy<1 || uy+dy>m) dy=-dy;
			
			ux+=dx, uy+=dy;
			v=add(v, 1);
			int w;
			if(ux==tx || uy==ty) w=p;
			else w=1;
			u=mul(u, w), v=mul(v, w);
		}
		
		cout<<(mul(v, inv(add(1, -u))))<<endl;
	}
	return 0;
}
posted @   HinanawiTenshi  阅读(141)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示