CSDN每日一练20230226

文章包含三道数学和算法相关的编程题目。第一题是关于小鱼的航程,要求计算在特定条件下小鱼游泳的总距离;第二题涉及运输石油的规划,目标是最大化利润;第三题则讨论n边形划分的问题,寻找连接对角线后形成的区域数量。每题都提出了不同的解题策略和优化方法。
摘要由CSDN通过智能技术生成

题目名称:小鱼的航程(改进版)(数学)

题目描述

有一只小鱼,它上午游泳150公里,下午游泳100公里,晚上和周末都休息(实行双休日),假设从周x(1<=x<=7)开始算起,请问这样过了n天以后,小鱼一共累计游泳了多少公里呢?

输入描述:

输入两个整数x,n(表示从周x算起,经过n天,n在long int范围内)。

输出描述:

输出一个整数,表示小鱼累计游泳了多少公里。

示例

输入 3 10
输出 2000

题目本身不难,由于数字比较大,不能用for循环去做,按周规整去做。
题目已提示n在long int范围,所以要用int64才行

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
void solution(int64_t x, int64_t n) {
	//从周1开始补齐获取总天数
	int64_t nn=n+x-1;
	int64_t s=nn/7*250*5;
	//额外的天数
	//printf("s:%d %d %d\n",s,nn,nn/7);
	int64_t nd=nn%7;
	for (int64_t i=0;i<nd;i++) {
		if(i<5) {
			s+=250;
		}
	}
	//printf("s:%d %d\n",s,nd);
	//减去开始补的天数
	for (int64_t i=1;i<x;i++) {
		if(i<6) {
			s-=250;
		}
	}
	//printf("s:%d %d\n",s,x);
	printf("%ld",s);
}
int main() {
	int64_t arr1[2];
	for (int i = 0; i < 2; i++) {
		scanf("%ld", &arr1[i]);
	}
	int64_t x = arr1[0];
	int64_t n = arr1[1];
	solution(x, n);
	return 0;
}

题目名称:运输石油(规划)

题目描述

某石油公司需要向A、B两地运输石油。两地的需求量不同,而一辆车只能装载一定量的石油。经过计算A地需要a辆车,B地需要b辆车运输才能满足需求。现在一共有n辆车分布在各地,每辆车前往A、B两地运输石油均可以获得一定不等的利润。 现在请你安排a辆车前往A地,b辆车前往B地运输石油,使得在满足A、B两地石油需求的前提下,获得最大的利润。每辆车只能前往一地运输石油。

输入描述:

输入第一行包含三个整数n,a,b,分别表示公司的车辆数量和A,B两地车辆所需数量,保证a+b<=n。(1<=n<=1000) 接下来有n行,每行两个正整数x,y,分别表示该车完成A地任务的利润和B地任务的利润。

输出描述:

输出仅包含一个正整数,表示最大获得的利润和。

示例
输入

5 2 2
4 2
3 3
5 4
5 3
1 5

输出

18

提示

将第3、4辆车派往A地,将第2、5辆车派往B地,将获得最大利润:5+5+3+5=18

题目存在多解
将第1、4辆车派往A地,将第3、5辆车派往B地,将获得最大利润:4+5+4+5=18
本来是想暴力破解,全排序遍历,但超时。
这里的方式,先假设都派到A地,然后计算每辆车A到B的差价,替换前b辆增益值高的。
将这到B的车和剩下的重新排序,重新选出b辆到B的汽车。
注意:我这里通过率只有90%

#include <stdio.h>
#include <stdlib.h>
//最终结果
int maxs=0;
int max(int a,int b) {
	if(a>b) {
		return a;
	} else {
		return b;
	}
}
//打印数组,测试用
#if 0
void showarr(int n,int (*arr)[2]) {
	for (int i=0;i<n;i++) {
		printf("i:%d %d %d\n",i,arr[i][0],arr[i][1]);
	}
	printf("******\n");
}
# else
void showarr(int n,int (*arr)[2]) {
}
#endif
//计算数值
//前a个到A公司,之后b个到B公司
int counts(int (*arr)[2],int a, int b) {
	int s=0;
	for (int i=0;i<a;i++) {
		s+=arr[i][0];
	}
	for (int i=a;i<a+b;i++) {
		s+=arr[i][1];
	}
	return s;
}
//数值交换
void swap(int (*arr)[2],int a,int b) {
	int tmp[2]= {
		0
	}
	;
	tmp[0]=arr[a][0];
	tmp[1]=arr[a][1];
	arr[a][0]=arr[b][0];
	arr[a][1]=arr[b][1];
	arr[b][0]=tmp[0];
	arr[b][1]=tmp[1];
}
//方法1全排序
void sortarray(int n, int a, int b, int (*arr)[2],int pos) {
	if(pos==n) {
		showarr(n,arr);
		maxs=max(maxs,counts(arr,a,b));
		return;
	}
	for (int i=pos;i<n;i++) {
		swap(arr,i,pos);
		sortarray(n,a,b,arr,pos+1);
		swap(arr,i,pos);
	}
}
//使用全排序
void solution(int n, int a, int b, int (*arr)[2]) {
	sortarray(n,a,b,arr,0);
}
//依次将pos位置赋值给A,B,不赋值三种情况
//检查a,b数量是否达到目标
void checkarray(int n, int a, int b, int (*arr)[2],int pos,int ca,int cb,int s) {
	if(ca==a&&cb==b) {
		maxs=max(maxs,s);
		return;
	}
	if(pos>=n) {
		return;
	}
	//数量不够直接返回
	if((a+b)-(ca+cb)>(n-pos)) {
		return;
	}
	if(ca<a) {
		s+=arr[pos][0];
		checkarray(n,a,b,arr,pos+1,ca+1,cb,s);
		s-=arr[pos][0];
	}
	if(cb<b) {
		s+=arr[pos][1];
		checkarray(n,a,b,arr,pos+1,ca,cb+1,s);
		s-=arr[pos][1];
	}
	checkarray(n,a,b,arr,pos+1,ca,cb,s);
}
//基于AB分配标识
void solution2(int n, int a, int b, int (*arr)[2]) {
	checkarray(n,a,b,arr,0,0,0,0);
}
//1号位高在前,其次2号位高在前
int cmp2(const void*pa,const void*pb) {
	int*a=(int*)pa;
	int*b=(int*)pb;
	if(a[0]<b[0]) {
		return 1;
	} else 
	  if(a[0]==b[0]) {
		return a[1]<b[1];
	} else {
		return 0;
	}
}
//a[1]-a[0]高的在前
int cmp3(const void*pa,const void*pb) {
	int*a=(int*)pa;
	int*b=(int*)pb;
	if((a[1]-a[0])==(b[1]-b[0])) {
		return a[1]<b[1];
	}
	return (a[1]-a[0])>(b[1]-b[0]);
}
int cmp4(const void*pa,const void*pb) {
	int*a=(int*)pa;
	int*b=(int*)pb;
	return a[1]<b[1];
}
void solution3(int n, int a, int b, int (*arr)[2]) {
	showarr(n,arr);
	qsort(arr,n,sizeof(int)*2,cmp2);
	showarr(n,arr);
	//比较前a+b个,转换值高的在后面,保证前面a个是个A公司的
	qsort(arr,a+b,sizeof(int)*2,cmp3);
	showarr(n,arr);
	//比较b到n位置,按b降序
	if(a+b<n) {
		qsort(arr+a,n-a,sizeof(int)*2,cmp4);
		showarr(n,arr);
	}
	//计算
	maxs=counts(arr,a,b);
}
int main() {
	int temp_arr[3];
	for (int i = 0; i < 3; i++) {
		scanf("%d", &temp_arr[i]);
	}
	int n = temp_arr[0];
	int a = temp_arr[1];
	int b = temp_arr[2];
	int (*arr)[2];
	arr = (int(*)[2])malloc(n * sizeof(int*));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < 2; j++) {
			scanf("%d", &arr[i][j]);
		}
	}
	//solution(n, a, b, arr);
	//solution2(n, a, b, arr);
	solution3(n, a, b, arr);
	printf("%d",maxs);
	return 0;
}

题目名称:n边形划分(数学公式)

题目描述

已知存在n多边形,n为奇数。 连接多边形所有对角线。 能形成多少区域。

输入描述:

给定整数n。(1<=n<=1e9)

输出描述:

输出区域数,对1e9+7取模

示例

输入 5
输出 11

就是要知道公式,
int64_t s=(n-1)(n-2)(n*n-3*n+12)/24;
可见以下完整
https://wenku.baidu.com/view/d4311009ac45b307e87101f69e3143323968f5d3.html
但提交时通过率为0%

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
void count(int i) {
	//int64_t s=(i-1)*(i-2)*(i*i-3*i+12)/24;
	//int64_t s=(i*i*i*i-6*i*i*i+23*i*i-42*i+24)/24;
	int64_t i2=i*i%1000000007;
	int64_t i3=i2*i%1000000007;
	int64_t i4=i3*i%1000000007;
	int64_t s=(i4-6*i3+23*i2-42*i+24)/24;
	//printf("%d %ld\n",i,s%1000000007);
	printf("%d",s);
}
void solution(int64_t n) {
	count(n);
	return;
	for (int i=3;i<n;i++) {
		count(i);
	}
}
int main() {
	int64_t n;
	scanf("%ld", &n);
	solution(n);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值