C - Monthly Expense

该博客探讨如何使用C语言解决一个优化问题,即如何最小化每月的最大支出。通过理解和解决问题,读者将能掌握C语言编程技巧以及解决实际财务优化问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://vjudge.net/contest/256497#problem/C

最小化最大消费

#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
#include<set>
#include<cstring>
#include<stack>
#include<iomanip>
#define mxan
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
using namespace std;
typedef long long ll;
const int N=2e6+100;
const ll IN=1e18;
const int maxn=1020;
int a[N];
int n,m,high=0,low=-1,mid,hhh;

bool slove(int x)
{
    int res=0,sum=0;
    for(int i=0;i<n;i++)
    {
        sum+=a[i];
        if(sum>x)
        {
            ++res;
            sum=a[i];
        }
    }
    res++;
    if(res>m) return false;

    else return true;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
        if(a[i]>low) low=a[i];
        high+=a[i];
    }
    while(low<high)
    {
        mid=(low+high)/2;
        if(slove(mid))
        {
            high=mid;
        }
        else
            low=mid+1;
    }
    mid = (low+ high ) / 2;
    cout<<mid<<endl;

}
我们仍然保留按月汇总的功能,但是输入时按天输入,然后程序内部按天存储,在需要按月显示时进行汇总#include <stdio.h> #include <stdlib.h> typedef struct { int month; // 月份 float income; // 收入 float food; // 伙食消费 float daily; // 日常用品费用 float utilities; // 水电费 float medical; // 医疗费 float entertainment; // 娱乐费用 float total; // 总开支 } Expense; //声明函数 void inputExpense(Expense expenses[]);//初始输入函数 void modifyExpense(Expense expenses[]);//修改函数 void sortExpenses(Expense expenses[]);//排序函数 void queryExpense(Expense expenses[]);//查询函数 void printExpenses(Expense expenses[]);//排列后开支情况总表打印函数 void saveExpensesToFile(Expense expenses[]);//文件写入 void loadExpensesFromFile(Expense expenses[]);//文件读取 void initExpenses(Expense expenses[]) { int i; for (i = 0; i < 12; i++) { expenses[i].month = i + 1; // 初始化月份为1到12 expenses[i].income = 0.0f; // 初始化收入为0 expenses[i].food = 0.0f; // 初始化伙食消费为0 expenses[i].daily = 0.0f; // 初始化日常用品费用为0 expenses[i].utilities = 0.0f; // 初始化水电费为0 expenses[i].medical = 0.0f; // 初始化医疗费为0 expenses[i].entertainment = 0.0f; // 初始化娱乐费用为0 expenses[i].total = 0.0f; // 初始化总开支为0 } } void saveExpensesToFile(Expense expenses[]) { FILE *file = fopen("expenses.txt", "w"); // 打开文件用于写入 if (file == NULL) { perror("无法打开文件"); return; } int i; for (i = 0; i < 12; i++) { fprintf(file, "%d %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", expenses[i].month, expenses[i].income, expenses[i].food, expenses[i].daily, expenses[i].utilities, expenses[i].medical, expenses[i].entertainment, expenses[i].total); } fclose(file); // 关闭文件 printf("数据已保存到文件\n"); } void loadExpensesFromFile(Expense expenses[]) { FILE *file = fopen("expenses.txt", "r"); // 打开文件用于读取 if (file == NULL) { perror("无法打开文件"); printf("将创建一个新文件\n"); return; } int i; for (i = 0; i < 12; i++) { if (fscanf(file, "%d %f %f %f %f %f %f %f", &expenses[i].month, &expenses[i].income, &expenses[i].food, &expenses[i].daily, &expenses[i].utilities, &expenses[i].medical, &expenses[i].entertainment, &expenses[i].total) != 8) { fprintf(stderr, "文件格式错误或数据不完整\n"); fclose(file); return; } } fclose(file); // 关闭文件 } void inputExpense(Expense expenses[]) { int month = 0; printf("请输入月份(1-12):"); scanf("%d", &month); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入收入:"); scanf("%f", &expenses[month - 1].income); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入伙食消费:"); scanf("%f", &expenses[month - 1].food); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入日常用品费用:"); scanf("%f", &expenses[month - 1].daily); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入水电费:"); scanf("%f", &expenses[month - 1].utilities); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入医疗费:"); scanf("%f", &expenses[month - 1].medical); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入娱乐费用:"); scanf("%f", &expenses[month - 1].entertainment); while (getchar() != '\n'); // 清除输入缓冲区 expenses[month - 1].month = month; expenses[month - 1].total = expenses[month - 1].food + expenses[month - 1].daily + expenses[month - 1].utilities + expenses[month - 1].medical + expenses[month - 1].entertainment; } void modifyExpense(Expense expenses[]) { int month = 0; printf("请输入要修改的月份(1-12):"); scanf("%d", &month); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入新的收入:"); scanf("%f", &expenses[month - 1].income); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入新的伙食消费:"); scanf("%f", &expenses[month - 1].food); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入新的日常用品费用:"); scanf("%f", &expenses[month - 1].daily); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入新的水电费:"); scanf("%f", &expenses[month - 1].utilities); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入新的医疗费:"); scanf("%f", &expenses[month - 1].medical); while (getchar() != '\n'); // 清除输入缓冲区 printf("请输入新的娱乐费用:"); scanf("%f", &expenses[month - 1].entertainment); while (getchar() != '\n'); // 清除输入缓冲区 expenses[month - 1].total = expenses[month - 1].food + expenses[month - 1].daily + expenses[month - 1].utilities + expenses[month - 1].medical + expenses[month - 1].entertainment; } void sortExpenses(Expense expenses[]) { int i, j, maxIndex;//选排 Expense temp; for (i = 0; i < 11; i++) { // 找到未排序部分的最小元素的索引 maxIndex = i; for (j = i + 1; j < 12; j++) { if (expenses[j].total > expenses[maxIndex].total) { maxIndex = j; } } // 将找到的最小元素与未排序部分的第一个元素交换 if (maxIndex != i) { temp = expenses[i]; expenses[i] = expenses[maxIndex]; expenses[maxIndex] = temp; } } } void queryExpense(Expense expenses[]) { int month = 0; printf("请输入要查询的月份(1-12):"); scanf("%d", &month); while (getchar() != '\n'); // 清除输入缓冲区 if (month < 1 || month > 12) { printf("无效的月份\n"); return; } printf("月份:%d\n", expenses[month - 1].month); printf("收入:%.2f\n", expenses[month - 1].income); printf("伙食消费:%.2f\n", expenses[month - 1].food); printf("日常用品费用:%.2f\n", expenses[month - 1].daily); printf("水电费:%.2f\n", expenses[month - 1].utilities); printf("医疗费:%.2f\n", expenses[month - 1].medical); printf("娱乐费用:%.2f\n", expenses[month - 1].entertainment); printf("总开支:%.2f\n", expenses[month - 1].total); } void printExpenses(Expense expenses[]) { printf("排序后的开支情况:\n"); int i; for (i = 0; i < 12; i++) { printf("月份:%d, 收入:%.2f, 伙食消费:%.2f, 日常用品费用:%.2f, 水电费:%.2f, 医疗费:%.2f, 娱乐费用:%.2f, 总开支:%.2f\n", expenses[i].month, expenses[i].income, expenses[i].food, expenses[i].daily, expenses[i].utilities, expenses[i].medical, expenses[i].entertainment, expenses[i].total); } } int main() { Expense expenses[12]; //假设一年有12个月 int j; for (j = 0;j <= 11;j++) { expenses[j].month= 0 ; } initExpenses(expenses); int choice; // 从文件加载数据 loadExpensesFromFile(expenses); do { printf("\n"); printf("1. 输入收支情况\n"); printf("2. 修改收支情况\n"); printf("3. 排序开支\n"); printf("4. 查询收支情况\n"); printf("5. 保存并退出\n"); printf("请输入您的选择:"); scanf("%d", &choice); while (getchar() != '\n'); // 清除输入缓冲区 switch (choice) { case 1: inputExpense(expenses); break; case 2: modifyExpense(expenses); break; case 3: sortExpenses(expenses); printf("开支已排序\n"); printExpenses(expenses);//打印排序后的结果 break; case 4: queryExpense(expenses); break; case 5: saveExpensesToFile(expenses); printf("退出系统\n"); return 0; default: printf("无效的选择,请重新输入\n"); } } while (choice != 5); return 0; }
最新发布
06-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值