题目名称:小鱼的航程(改进版)(数学)
题目描述
有一只小鱼,它上午游泳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;
}