洛谷评测链接:https://www.luogu.com.cn/problem/list?tag=363&page=4

A.移动距离

小明初始在二维平面的原点,他想前往坐标(233,666)。在移动过程中,他
只能采用以下两种移动方式,并且这两种移动方式可以交替、不限次数地使用:

  1. 水平向右移动,即沿着x轴正方向移动一定的距离。
  2. 沿着一个圆心在原点(0,0)、以他当前位置到原点的距离为半径的圆的圆
    周移动,移动方向不限(即顺时针或逆时针移动不限)。
    在这种条件下,他到达目的地最少移动多少单位距离?
    你只需要输出答案四舍五入到整数的结果

思路

弧长+半径  弧度数 = 角度*半径![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6faa6ddc256842bf83e02163bdab27e6.jpeg)

在这里插入图片描述

答案
#include<bits/stdc++.h>
using namespace std;

const int N = 5e5+10;
typedef long long ll;

int main(){
	
	int x = 233;
	int y = 666;
	double res = atan(y*1.0/x);
	cout<<(int)(res*sqrt(x*x+y*y)+sqrt(x*x+y*y))<<endl; 

	return 0;
}

B 客流量上限

一家连锁旅馆在全国拥有2025个分店,分别编号为1至2025。随着节日
临近,总部决定为每家分店设定每日客流量的上限,分别记作A1,A2,…,A2025。
这些上限并非随意分配,而是需要满足以下约束条件:

  1. A1,A2,…, A2025 必须是 1 至 2025 的一个排列,即每个 Ai 均是 1 至 2025
    之间的整数,且所有Ai互不相同。
  2. 对于任意分店i和 j(1≤i, j≤2025,i 可等于 j),它们的客流量上限 Ai
    和Aj 的乘积不得超过i× j+2025。
    这些约束旨在平衡各分店客流压力,确保服务质量和运营稳定性。
    现在,请你计算这样的分配方案究竟有多少种。由于答案可能很大,你只
    需输出其对109+7取余后的结果即可

思路

全排列找规律 1 1 2 2 4 4 8 8 16 16
故答案为 2^(2025/2)

#include<bits/stdc++.h>
using namespace std;

const int N = 5e5+10;
typedef long long ll;

int a[15]={0,1,2,3,4,5,6,7,8,9,10,11,12,13};
int main(){
	
	//枚举前11位
	for(int z=1;z<=11;z++){
		int res=0;
		do{
			int f = 0;
			for(int i=1;i<=z;i++){
				for(int j=1;j<=z;j++){
					//判断是否合法
					if(a[i]*a[j]>i*j+z) f=1;
				}
			}
			if(!f) res++;
		}while(next_permutation(a+1,a+z+1));
		cout<<res<<" ";
	}

	return 0;
}
答案
#include<bits/stdc++.h>
using namespace std;

const int N = 5e5+10;
typedef long long ll;
const int mod = 1e9+7;
int a[15]={0,1,2,3,4,5,6,7,8,9,10,11,12,13};
int main(){
	
	ll n = 2025;
	ll res=1;
	ll k = n/2;
	for(int i=1;i<=k;i++){
		res=(res*2)%mod;
	
	}
	cout<<res%mod<<endl;

	return 0;
}

C.可分解的正整数

【问题描述】
定义一种特殊的整数序列,这种序列由连续递增的整数组成,并满足以下
条件:

  1. 序列长度至少为3。
  2. 序列中的数字是连续递增的整数(即相邻元素之差为1),可以包括正整
    数、负整数或0。
    例如,[1,2,3]、[4,5,6,7] 和 [−1,0,1] 是符合条件的序列,而 [1,2](长度不
    足)和[1,2,4](不连续)不符合要求。
    现给定一组包含N 个正整数的数据A1,A2,…,AN。如果某个 Ai 能够表示
    为符合上述条件的连续整数序列中所有元素的和,则称Ai是可分解的。
    请你统计这组数据中可分解的正整数的数量
    【输入格式】
    输入的第一行包含一个正整数N,表示数据的个数。
    第二行包含N个正整数A1,A2,…,AN,表示需要判断是否可分解的正整数
    序列。
    【输出格式】
    输出一个整数,表示给定数据中可分解的正整数的数量。
    【样例输入】
    3
    3 6 15
    【样例输出】
    3

思路

统计非1的数量

答案
#include<bits/stdc++.h>
using namespace std;

const int N = 5e5+10;
typedef long long ll;
const int mod = 1e9+7;

int n;
int main(){
	
	scanf("%d",&n);
	int res=0;
	for(int i=1;i<=n;i++){
		int x;
		cin>>x;
		if(x!=1) res++;
	}
		cout<<res<<endl;

	return 0;
}

D.产值调整

在这里插入图片描述
在这里插入图片描述

思路

找规律 经过几次变换后 A B C 会变为相同值

答案
#include<bits/stdc++.h>
using namespace std;

const int N = 5e5+10;
typedef long long ll;

int pd(int a,int b){
	double res = (a+b)/2;
	res*=10;
	return res/10;
}
void solve(){
	
	int a,b,c,k;
	cin>>a>>b>>c>>k;
	int sa,sb,sc;
	sa= a,sb=b,sc=c;
	for(int i=0;i<k;i++){
		if(sa==sb&&sb==sc){
			break;
		}
		a = pd(sb,sc);
		b = pd(sa,sc);
		c = pd(sa,sb);
		sa = a,sb = b,sc = c;	
	}
	cout<<a<<" "<<b<<" "<<c<<endl;
}
int main(){
	
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	
	
	return 0;
}

E. 画展布置

在这里插入图片描述

思路

解法一 滑动窗口+差分+排序
解法二 前缀和 +排序

答案一
#include<bits/stdc++.h>
using namespace std;

const int N = 1e5+10;
typedef long long ll;
ll a[N];
ll b[N];
int n,m;
int main(){
	cin>>n>>m;
	ll ans=0;
	for(int i=1;i<=n;i++){
		int x;
		cin>>x;
		a[i]=(ll)x*x;
	
		
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		b[i] = a[i]-a[i-1];
		ans+=b[i];
	}
	ll sum = 0;

	for(int i=1;i<=n;i++){
		sum+=b[i];
		if(i<m) continue;
		ans = min(ans,sum-b[i-m+1]);
		
		sum-=b[i-m+1];
	
	}
	cout<<ans<<endl;
	return 0;
}
答案二
#include<bits/stdc++.h>
using namespace std;

const int N = 1e5+10;
typedef long long ll;
ll a[N];
ll b[N];
int n,m;
int main(){
	cin>>n>>m;
	ll ans=1e18;
	for(int i=1;i<=n;i++){
		int x;
		cin>>x;
		a[i]=(ll)x*x;	
	}
	sort(a+1,a+n+1);
	ll sum = 0;
	for(int i=m;i<=n;i++){
		sum = a[i]-a[i-m+1];
		ans = min(ans,sum);
	}
	cout<<ans<<endl;
	return 0;
}

F. 水质检测

在这里插入图片描述

思路

贪心 + 动态规划
s1为第一行河床 s2 为第二行河床
d[0][i] 存储第一行到达i位置的最近检测器#的下表
d[1][i] 存储第二行到达i位置的最近检测器#的下表
故有4种情况

答案
#include<bits/stdc++.h>
using namespace std;

const int N = 5e5+10;
typedef long long ll;

string a,b;
int d[2][1000010];
int main(){
	
	cin>>a>>b;
	int res=0;
	int t;
	memset(d,-0x3f3f3f3f,sizeof(d));
		for(int i=0;i<a.size();i++){
			if(a[i]!='.'||b[i]!='.') {
				if(a[i]!='.')
				d[0][i] = i;
				if(b[i]!='.')
				d[1][i] = i;
				t = i;
				break;
			}
		}
		for(int i=t+1;i<a.size();i++){
			if(a[i]=='#'&&b[i]=='#'){
				d[0][i] = i;
				d[1][i] = i;
				res+=min(i-d[0][i-1]-1,i-d[1][i-1]-1);
				continue;
			}
			if(a[i]=='#'&&b[i]=='.'){
				if(i-d[0][i-1]-1<i-d[1][i-1]) {
					d[0][i] = i;
					d[1][i] = d[1][i-1];
				}
				else {
					d[0][i] = i;
					d[1][i] = i;
				}
				res+=min(i-d[0][i-1]-1,i-d[1][i-1]);
				continue;
			}
			if(a[i]=='.'&&b[i]=='#'){
				if(i-d[1][i-1]-1<i-d[0][i-1]){
					d[0][i] = d[0][i-1];
					d[1][i] = i;
				}
				else{
					d[0][i] = i;
					d[1][i] = i;
				}

				res+=min(i-d[0][i-1],i-d[1][i-1]-1);
				continue;
			}
			d[0][i] = d[0][i-1];
			d[1][i] = d[1][i-1];
	
		}
	
	cout<<res<<endl;
	return 0;
}

G. 生产车间

在这里插入图片描述

思路

树形dp

答案
#include<bits/stdc++.h>
using namespace std;

const int N = 1e3+10;
typedef long long ll;
int n;
int a[N], dp[N][N];
vector<int> g[N];
int res;
void dfs(int x, int fa, int val){
	if(g[x].size() == 1 && g[x][0] == fa){
		
		dp[x][a[x]] = a[x];
		return;
	}
	for(int i = 0;i<g[x].size();i++){
		int j = g[x][i];
		if(j == fa) continue;
		dfs(j, x, min(val,a[j]));
		for(int z = val;z >= 0; --z){
			for(int k = 0;k <= min(a[j], z); ++k){
				dp[x][z]= max(dp[x][z-k] + dp[j][k], dp[x][z]);
				res = max(dp[x][z], res);
				
			}
		}
	}
	return;
}
int main(){

	cin >> n;
	for(int i = 1;i <= n; ++i) cin >> a[i];
	int x, y;
	for(int i = 1;i < n; ++i){
		cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs(1, 1, a[1]);
	cout << res <<endl;
	return 0;
}

H. 装修报价

未完待续…

Logo

集算法之大成!助力oier实现梦想!

更多推荐