8.30总结

T1

签到题,不写了

T2

题目要求我们求每一种方案中的多米诺数量总和
对于一个新的点,它的答案是上一个点的答案加上这个点的方案书
数,因为每一个方案都要加上一个新的多米诺

状态:dp[i]:第i个点的答案  pd[i]:第i个点的方案数
答案:dp[n]
方程:dp[i]+=dp[i-1]+dp[i-2]+dp[i-3]+pd[i];
     pd[i]+=pd[i-1];
初始值:dp[1]=dp[2]=dp[3]=1,pd[1]=pd[2]=pd[3]=1;
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int maxn=1e6+5,mod=99824353,inf=1e18;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
void write(int x){if(x<0){putchar('-'),x=-x;}if(x>9){write(x/10);}putchar(x%10+'0');return;}
int fpow(int a,int b,int p){if(b==0){return 1;}int res=fpow(a,b/2,p)%p;if(b%2==1){return((res*res)%p*a)%p;}else{return(res*res)%p;}}
int t,n,dp[maxn],pd[maxn];
void solve(){
	cin>>n;
	memset(dp,0,sizeof(dp));
	memset(pd,0,sizeof(pd));
	dp[1]=dp[2]=dp[3]=1;
	pd[1]=pd[2]=pd[3]=1;
	for(int i=2;i<=n;i++){
		dp[i]+=dp[i-1]+pd[i-1];
		pd[i]+=pd[i-1];
		dp[i]%=mod;
		pd[i]%=mod;
		if(i-2>=1){
			dp[i]+=dp[i-2]+pd[i-2];
			pd[i]+=pd[i-2];
			dp[i]%=mod;
			pd[i]%=mod;
		}
		if(i-3>=1){
			dp[i]+=dp[i-3]+pd[i-3];
			pd[i]+=pd[i-3];
			dp[i]%=mod;
			pd[i]%=mod;
		}
	}
	cout<<dp[n]%mod<<endl;
}
signed main(){
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

T3

距离和时间具有单调性,考虑二分
我们直接二分距离,对于每个答案,算一下总时间,如果合格就改rt,否则改lt

点击查看代码
#include<bits/stdc++.h>
#define double long double
#define int long long
#define endl "\n"
using namespace std;
const int maxn=1e6+5,mod=1e9+7,inf=1e18;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
void write(int x){if(x<0){putchar('-'),x=-x;}if(x>9){write(x/10);}putchar(x%10+'0');return;}
int fpow(int a,int b,int p){if(b==0){return 1;}int res=fpow(a,b/2,p)%p;if(b%2==1){return((res*res)%p*a)%p;}else{return(res*res)%p;}}
double n;
double a[maxn],m,sum;
double x;
double ans;
double b[maxn];
bool check(int x){
	int xx=0;
	for(int i=1;i<=n;i++){
		xx+=ceil(a[i]/(1.0*x));
	}
	return xx<=m;
}
void solve(){
	int lt=0,rt=inf;
	while(lt<rt){
		int mid=(lt+rt)/2;
		if(check(mid)){
			rt=mid;
		}
		else{
			lt=mid+1;
		}
	}
	cout<<lt<<endl;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i]>>x;
		m-=x;
	}
	if(m<=0){
		cout<<-1<<endl;
		return 0;
	}
	solve();
	return 0;
}

T4

原公式:

\[|x_1-x_2|+|y_1-y_2| \]

我们拆一下

\[\max(x_1-x_2,x_2-x_1)+\max(y_1-y_2,y_2-y_1) \\ 令x_1-x_2为a_1,x_2-x_1为a_2,y_1-y_2为a_3,y_2-y_1为a_4 \\ =\max(a_1+a_3,a_1+a_4,a_2+a_3,a_2+a_4) \\ =\max(\\ \ \ x_1-x_2+y_1-y_2\\ x_2-x_1+y_1-y_2\\ x_2-x_1+y_2-y_1\\ x_1-x_2+y_2-y_1\\ ) 我们单独考虑第一种情况 x_1-x_2+y_1-y_2 =(x_1+y_1)-(x_2+y_2) 我们要前一个尽可能大,后一个尽可能小 后面三个同理 \]

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int maxn=1e6+5,mod=1e9+7,inf=1e18;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
void write(int x){if(x<0){putchar('-'),x=-x;}if(x>9){write(x/10);}putchar(x%10+'0');return;}
int fpow(int a,int b,int p){if(b==0){return 1;}int res=fpow(a,b/2,p)%p;if(b%2==1){return((res*res)%p*a)%p;}else{return(res*res)%p;}}
int n,m;
void solve(){
	n=read();
	m=read();
	int minu=inf,maxu=-inf;
	int minv=inf,maxv=-inf;
	for(int i=1;i<=n;i++){
		int x,y;
		x=read();
		y=read();
		int u=x+y;
		int v=x-y;
		if(u<minu){
			minu=u;
		}
		if(u>maxu){
			maxu=u;
		}
		if(v<minv){
			minv=v;
		}
		if(v>maxv){
			maxv=v;
		}
	}
	int ans=inf;
	for(int i=1;i<=m;i++){
		int x,y;
		x=read();
		y=read();
		int u=x+y;
		int v=x-y;
		int dis1=max(u-minu,maxu-u);
		int dis2=max(v-minv,maxv-v);
		ans=min(ans,max(dis1,dis2));
	}
	write(ans);
	printf("\n");
}
signed main(){
	int t;
	t=read();
	while(t--){
		solve();
	}
	return 0;
}
posted @ 2025-08-30 17:04  KK_SpongeBob  阅读(10)  评论(0)    收藏  举报