第十五周项目1-工资数据的输入(2)

本文详细阐述了排序算法的设计与优化过程,通过实例展示了如何在实际应用中提高算法效率。
/*
* 程序的版权和版本声明部分:
* Copyright (c) 2013, 烟台大学计算机学院
* All rights reserved.
* 文件名称:.cpp
* 作    者:王英华
* 完成日期:2014年 6月 3日
* 版 本 号:v12.1
* 输入描述:略
* 问题描述:略
* 程序输出:略
* 问题分析:略
* 算法设计:略
*/
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    freopen("a.txt","r",stdin);
    double salarys[500],t;
    int n=0;
    while(cin>>salarys[n])
    {
        n++;
    }
    for(int i=0;i<n-1;i++)
    {
        for(int j=i;j<n-i-1;j++)
        if(salarys[i]<salarys[j])
        {
            t=salarys[i];
            salarys[i]=salarys[j];
            salarys[j]=t;
        }
    }
    for(int i=0;i<n;i++)
    {
        cout<<salarys[i]<<"  ";
    }
    fclose(stdin);
    return 0;
}
运行结果:
<think>题目要求处理多组输入数据,每组数据包含两个整数N和K,分别表示程序员的年薪(单位:万)和房价年增长率(百分比)。我们需要计算程序员在第几年能够买下房子(第一年房价200万,第一年结束时储蓄为N万,但房价在第一年结束时已经上涨)。 注意:题目要求“有多行”输入,因此我们需要一个循环来读取多行输入,直到没有输入为止。 关键点: 1. 第一年(year=1)结束时,程序员储蓄了N万(即N*10000元),同时房价在年初200万的基础上上涨K%,变为200*(1+K/100)万。 2. 在第二年及以后,每年储蓄增加N万,同时房价在前一年的基础上再上涨K%。 3. 我们需要判断在20年以内(包括第20年)是否有某一年结束时,储蓄总额大于等于当年的房价。 步骤: - 初始化:初始房价为200万(2000000元),储蓄总额为0。 - 从第一年开始循环到第20年(包括): - 每年储蓄增加:N * 10000(因为年薪N万,即N*10000元) - 第一年年初房价为200万,但第一年结束时房价已经上涨(即乘以1+K/100)。注意:在判断第一年结束能否购买时,房价已经是上涨后的价格。 - 对于后续年份,在每年结束时,我们也要先计算房价(即在上一年末房价的基础上再上涨K%),然后判断储蓄是否够。 但是注意:题目中第一年房价200万,然后第一年结束就上涨了。所以我们在第一年结束的时候,房价已经上涨了。因此,在循环中,对于每一年,我们可以在储蓄增加后,先计算当年的房价(如果是第一年,则用200万乘以增长率;之后的年份则用上一年的房价乘以增长率),然后判断。 另一种处理方式:在循环开始前设置初始房价为200万,然后进入循环: - 第一年:储蓄增加N万,然后房价立即上涨(即乘以1+K/100),然后判断。 - 第二年:储蓄再增加N万,然后房价再上涨,再判断。 具体步骤(循环内): 1. 储蓄总额 += N * 10000 2. 如果是第一年,那么房价 = 2000000 * (1 + K/100) 3. 如果不是第一年,那么房价 = 上一年的房价 * (1 + K/100) 4. 判断当前储蓄总额是否大于等于当前房价,如果是,则输出当前年数(即循环到第几年),并跳出循环。 5. 如果循环到20年都没有满足,则输出"Impossible" 但是注意:题目要求有多组输入,所以我们需要一个循环来读取每一行的N和K,并对每一组数据计算。 由于题目没有明确输入结束的条件,我们可以使用以下方法读取多行: while True: try: line = input().split() if not line: break N = int(line[0]); K = int(line[1]) # 进行计算 except EOFError: break 或者更简洁的写法: import sys for line in sys.stdin: data = line.split() if not data: continue N = int(data[0]); K = int(data[1]) # 进行计算 但是题目描述是“有多行”,所以我们可以使用: 代码结构: while True: try: data = input().split() if not data: break N = int(data[0]) K = int(data[1]) # 计算该组数据 house_price = 2000000 # 初始房价,单位元 savings = 0 flag = False # 标记是否在20年内找到 for year in range(1, 21): # 从第1年到第20年 savings += N * 10000 # 每年储蓄增加 # 每年房价上涨(注意:第一年年初是200万,第一年结束就上涨了) house_price = house_price * (1 + K/100) # 判断当前储蓄是否足够 if savings >= house_price: print(year) flag = True break if not flag: print("Impossible") except EOFError: break 但是,注意:在每一年的开始,房价就已经是上一年结束时的价格(即已经上涨过了),而我们在第一年循环内,第一次计算house_price时,是用200万乘以(1+K/100),这是正确的。因为第一年结束的时候,房价才上涨,而我们在第一年结束时才判断。 然而,这里有一个细节:我们是在每年储蓄增加后,再计算房价上涨,然后再判断。也就是说,在第一年,我们储蓄增加(变成N万),然后房价上涨(变成200*(1+K/100)万),然后判断储蓄是否大于等于房价。 但是,实际上,第一年年初房价是200万,但第一年结束的时候房价才上涨。而储蓄是年底才有的。所以这个顺序是合理的。 另一种理解:每年流程如下: 年初:没有储蓄增加(因为工资是年底发) 年底:发工资,储蓄增加N万;然后房价上涨K%。 所以,我们代码中的顺序:先加储蓄,再计算房价上涨,再判断。这样,在判断时,储蓄是当年新增的,而房价是当年上涨后的。这样,第一年结束时,储蓄就是N万,房价是200万*(1+K/100)。 但是,这里有一个问题:在第二年及以后,我们也是先加储蓄再计算房价上涨。那么第二年的房价上涨是在第二年末发生的,所以第二年末的房价是第二年初的房价(即第一年末的房价)乘以(1+K/100),然后再加上第二年的储蓄,然后判断。这个逻辑是符合题意的。 然而,我们再看题目:第一年房价200万,第一年结束的时候房价上涨,然后程序员有第一年的储蓄N万。所以第一年结束,我们判断:储蓄N万是否大于等于上涨后的房价(200万*(1+K/100))?如果大于,则第一年结束就可以买。 但是,实际上,第一年结束的时候,房价已经上涨了,而程序员只有第一年的储蓄,所以通常第一年是不够的。 所以,代码逻辑正确。 但是,我们也可以这样写:将房价上涨放在储蓄增加之前?这样就不对了。因为第一年年初房价是200万,而第一年结束的时候,先发工资,然后房价再上涨。所以,我们应该是先有储蓄,然后房价才上涨。所以先储蓄,再房价上涨,再判断。 但是,另一种观点:房价上涨是发生在这一年的过程中,而储蓄是在年底一次性增加的。所以,在年底,我们同时拥有储蓄增加和房价上涨。所以,我们可以在年底先计算储蓄,然后计算房价上涨,然后判断。这样,在判断时,房价已经上涨了,而储蓄也已经增加了。 所以,代码顺序为: 储蓄增加 房价上涨 判断 因此,上面的代码逻辑正确。 但是,我们也可以这样:在循环开始,先计算房价上涨(除了第一年?)。不对,因为第一年年初是200万,第一年结束的时候才上涨。所以,在循环内,我们对于每一年(包括第一年)都要计算房价上涨(第一年从200万上涨,第二年从第一年末的房价上涨,等等)。所以,我们可以在循环内统一处理:每年都先计算房价上涨?但是这样第一年就不对了,因为第一年年初是200万,我们还没有开始循环。所以,我们可以在循环内,对于每一年,先计算储蓄,再计算房价上涨(这样第一年计算房价上涨时,就是200万乘以系数,而第二年就是上一年的房价乘以系数)。 因此,代码结构不变。 但是,注意:在进入循环之前,房价是200万。在循环的第一年: 储蓄增加:savings = 0 + N*10000 然后房价上涨:house_price = 2000000 * (1+K/100) 然后判断 在第二年: 储蓄增加:savings = N*10000 + N*10000 = 2*N*10000 然后房价上涨:house_price = [2000000*(1+K/100)] * (1+K/100) = 2000000*(1+K/100)^2 然后判断 以此类推。 所以,这样是符合的。 但是,我们也可以将房价上涨放在储蓄增加之前?那么第一年: 先房价上涨:house_price = 2000000*(1+K/100) (此时储蓄还是0) 然后储蓄增加:savings = 0 + N*10000 然后判断:此时储蓄是N万,房价是200*(1+K/100)万,然后判断。 这样也是合理的,因为房价上涨发生在这一年中,而储蓄发生在年底。所以,在年底的时候,房价已经涨了,然后才发工资。所以,先计算房价上涨,再增加储蓄,再判断。 这两种顺序其实都是模拟同一时间点:年底。因为房价上涨和储蓄增加都是在年底这个时间点完成的,所以谁先谁后并不影响数值(因为判断是在两者都完成之后)。但是,从逻辑上,我们更倾向于:年底先发工资(储蓄增加),然后房价再上涨?或者反过来?题目没有明确。但是,从题目的描述“第一年房价200万,收入N万”以及“房子价格以每年百分之K增长”,并且第一年结束时,房价就上涨了。同时,第一年结束时,程序员有了第一年的收入。所以,在年底这个时间点,储蓄和上涨后的房价同时存在。 所以,无论先计算储蓄还是先计算房价,只要在判断前两者都更新了,结果是一样的。但是,如果我们先计算房价上涨,那么第一年储蓄增加前,房价已经涨了,然后储蓄增加,然后判断。那么第一年的房价就是200*(1+K/100),而储蓄是N万。 所以,两种写法都可以。 这里,我们采用先增加储蓄再计算房价上涨(因为题目描述的顺序是:每年所得N万积攒起来,然后房子价格增长,所以先有收入,然后房价再涨?但实际上,房价增长是贯穿全年的,而收入是年底发的。所以严格来说,应该是年底的时候,收入到账,同时房价也完成了增长。因此,我们也可以将两者视为同时发生。但为了符合题目的文字顺序,我们采用先储蓄再房价上涨。 但是,如果我们先计算房价上涨,那么第一年年初的200万在循环内第一次就变成了上涨后的价格,然后储蓄增加,然后判断。这样,第一年结束时,房价已经上涨了,储蓄也增加了,然后判断。这样也是正确的。 所以,为了明确,我们这样写: 第一年循环: 储蓄 = 0 + N*10000 房价 = 2000000 * (1+K/100) # 第一年结束,房价上涨 判断:储蓄>=房价? 第二年循环: 储蓄 = 第一年储蓄 + N*10000 房价 = 第一年结束的房价 * (1+K/100) # 第二年结束,房价再次上涨 判断 这样,第一年结束的房价是200万上涨一次后的价格,而储蓄是第一年的储蓄。 但是,如果我们先计算房价上涨,那么: 第一年循环: 房价 = 2000000 * (1+K/100) # 此时房价变成第一年末的房价 储蓄 = 0 + N*10000 判断 第二年循环: 房价 = 当前房价(即第一年末的房价) * (1+K/100) # 变成第二年末的房价 储蓄 = 第一年储蓄 + N*10000 判断 两种方法结果一样。因为都是:第一年末的房价=200*(1+K/100),储蓄=N;第二年末的房价=200*(1+K/100)^2,储蓄=2N。 所以,我们选择一种即可。 这里,我们选择先储蓄增加,再房价上涨,再判断。因为题目描述中,先提到收入积攒,再提到房价增长(虽然是一年一次,但顺序没有明确,但按照“先有收入再考虑房价增长”的理解,先储蓄再涨价)。 但是,我们也可以这样想:房价在一年中逐渐增长,到年底才涨到预定值,而收入也是年底才到账。所以,在年底,收入到账的同时,房价也涨到了预定值。所以,我们也可以将两个计算视为同时进行,不分先后。但代码中总有一个先后顺序。 因此,我们按照下面的顺序: 每年循环: 储蓄增加 房价上涨(乘以1+K/100) 判断 这样,在判断时,储蓄和房价都是当年结束时的值。 注意:我们使用浮点数计算,但要注意浮点数精度问题。由于金额较大,但题目中N和K都是整数,且范围不大,所以浮点数精度问题可能不会造成太大影响。但为了严谨,我们也可以考虑使用整数计算(例如,将K转换为小数,然后使用浮点数,最后比较时考虑舍入)。 但是,题目没有要求舍入,所以我们直接比较浮点数。由于金额单位是元,而房价和储蓄都是整数元(但房价乘以增长率后可能不是整数),所以储蓄是整数(每年增加N万,即整数元),而房价可能是小数。那么,我们判断储蓄(整数)是否大于等于房价(浮点数)?可以,因为储蓄是整数,而房价可能是小数,所以只要储蓄大于等于房价的整数部分(向上取整?)?但题目没有说房价可以分,所以通常我们理解为房价的最小单位是元,即房价上涨后也是整数元?但题目没有明确,所以我们按照浮点数比较。 但是,题目中的例子:100万,10%的增长,第一年变成220万,第二年变成242万,第三年变成266.2万,但266.2万就是2662000元。而储蓄在第三年是300万(3000000元),大于2662000,所以可以购买。 所以,我们直接比较浮点数即可。 另外,如果刚好相等,那自然是可以购买。如果储蓄大于房价,也可以购买。 代码实现: 注意:由于有多组输入,我们需要对每一组输入都进行计算,并输出结果(每组输出占一行)。 我们使用try-except来捕获输入结束。 具体代码: ```python import sys def main(): # 使用sys.stdin读取多行 for line in sys.stdin: # 跳过空行 if line.strip() == '': continue data = line.split() if len(data) < 2: continue try: N = int(data[0]) K = int(data[1]) except: continue # 初始化 house_price = 2000000.0 # 初始房价200万,单位元 savings = 0.0 found = False # 从第一年到第20年 for year in range(1, 21): savings += N * 10000 # 每年储蓄增加N万,即增加N*10000元 # 房价上涨: 注意,第一年也要上涨 house_price *= (1 + K / 100.0) # 判断当前储蓄是否足够 if savings >= house_price: print(year) found = True break if not found: print("Impossible") if __name__ == '__main__': main() ``` 但是,我们也可以考虑在循环内先储蓄后房价上涨,然后判断,这样第一年结束时,房价已经上涨了一次。 但是,上面的代码中,在循环的第一年,我们增加了储蓄,然后房价上涨(即乘以系数),然后判断。这样,第一年结束时的房价就是200万*(1+K/100),储蓄就是N万。 但是,我们也可以测试一下:如果N=200,K=0,那么第一年结束,储蓄=200万,房价=200万,所以第一年就可以买,输出1。符合。 如果N=100,K=0,那么第一年:储蓄=100万,房价=200万,不够;第二年:储蓄=200万,房价=200万(因为K=0,没有增长),所以第二年可以买,输出2。符合。 如果N=100, K=10:第一年:储蓄=100万,房价=200*1.1=220万,不够;第二年:储蓄=200万,房价=220*1.1=242万,不够;第三年:储蓄=300万,房价=242*1.1=266.2万,300>=266.2,所以第三年可以买,输出3。符合。 如果N=50, K=10:我们计算一下: 第一年:50万 vs 220万 -> 不足 第二年:100万 vs 242-> 不足 第三年:150万 vs 266.2-> 不足 第四年:200万 vs 292.82-> 不足 第五年:250万 vs 322.102-> 不足 第六年:300万 vs 354.3122-> 不足 第七年:350万 vs 389.74342-> 不足 第八年:400万 vs 428.717762-> 不足 第九年:450万 vs 471.5895382-> 不足 第十年:500万 vs 518.748492-> 不足 第十一年:550万 vs 570.6233412-> 不足 第十二年:600万 vs 627.6856753万 -> 不足 第十三年:650万 vs 690.4542429万 -> 不足 第十四年:700万 vs 759.4996672-> 不足 第十五年:750万 vs 835.4496339万 -> 不足 第十六年:800万 vs 918.9945973万 -> 不足 第十七年:850万 vs 1010.894057万 -> 不足 第十八年:900万 vs 1111.983463万 -> 不足 第十九年:950万 vs 1223.181809万 -> 不足 第二十年:1000万 vs 1345.49999万 -> 不足 所以20年都不够,输出Impossible。 因此,代码逻辑正确。 注意:浮点数计算可能存在精度问题,但在这个范围内(20次方)应该可以接受。如果担心,可以使用decimal模块,但题目没有要求,且输入范围不大,所以浮点数足够。 另外,题目要求输出换行,所以每次输出后自动换行(print函数默认换行)。 所以,上述代码满足要求。 但是,我们也可以不使用sys.stdin,而使用try-except来读取输入直到EOF: ```python while True: try: data = input().split() N = int(data[0]) K = int(data[1]) # 计算 house_price = 2000000.0 savings = 0.0 found = False for year in range(1, 21): savings += N * 10000 house_price *= (1 + K / 100.0) if savings >= house_price: print(year) found = True break if not found: print("Impossible") except: break ``` 这样也可以,当输入结束时(遇到EOF)退出循环。 我们选择其中一种方式即可。 这里,我们选择第二种,因为更简洁。 但是,注意:如果输入行中有非数字字符,或者数据不足两个,那么int(data[0])或int(data[1])会出错。题目保证输入是整数,但可能不足两个?所以我们可以检查data的长度。 修改一下: ```python while True: try: data = input().split() if len(data) < 2: continue N = int(data[0]) K = int(data[1]) house_price = 2000000.0 savings = 0.0 found = False for year in range(1, 21): savings += N * 10000 house_price *= (1 + K / 100.0) if savings >= house_price: print(year) found = True break if not found: print("Impossible") except EOFError: break except: # 如果出现其他错误(比如转换整数失败),跳过该行 continue ``` 这样,如果一行输入不足两个,或者转换失败,我们就跳过这行(继续下一行)。直到遇到EOF结束。 但是,题目描述是“有多行,每行两个整数”,所以正常情况下不会出现错误,但为了健壮性,我们这样处理。 因此,最终代码:</think>根据问题描述,我们需要编写一个Python程序处理多组输入数据(年薪N和房价增长率K),计算程序员在第几年能买下初始200万的房子(每年储蓄N万,房价年增长K%)。以下是完整的解决方案: ```python def calculate_home_purchase(): import sys for line in sys.stdin: try: # 解析输入数据 data = line.split() if not data: continue N = int(data[0]) K = int(data[1]) # 初始化变量(单位:元) house_price = 2000000.0 # 初始房价 savings = 0.0 # 累计储蓄 found = False # 是否找到解决方案 # 检查20年内的购房可能 for year in range(1, 21): savings += N * 10000 # 每年储蓄年薪 house_price *= (1 + K / 100.0) # 房价年增长 # 检查是否可购房 if savings >= house_price: print(year) found = True break # 20年内无法购房 if not found: print("Impossible") except: # 跳过无效输入行 continue if __name__ == "__main__": calculate_home_purchase() ``` ### 关键逻辑说明: 1. **输入处理**: - 使用`sys.stdin`读取多行输入 - 每行包含两个整数:年薪$N$(10-50)和增长率$K$(1-20) 2. **核心计算**: - **储蓄累计**:每年增加$N \times 10000$元 - **房价增长**:每年按$(1 + \frac{K}{100})$倍增长 - **购房条件**:满足$ \text{savings} \geq \text{house\_price} $ 3. **终止条件**: - 满足购房条件时输出当前年数$M$ - 20年未满足则输出"Impossible" 4. **浮点数处理**: - 使用浮点数计算房价增长 - 考虑浮点精度问题(金额范围下不影响结果) ### 示例测试: | 输入 (N, K) | 输出 | 说明 | |------------|------------|--------------------------------------| | `100 0` | `2` | 第2年末储蓄200万=房价200万 | | `200 0` | `1` | 第1年末储蓄200万≥房价200万 | | `100 10` | `3` | 第3年末储蓄300万≥房价266.2万 | | `50 20` | `Impossible` | 20年内储蓄始终低于增长后的房价 | ### 计算示例(N=100, K=10): 1. **第1年末**: - 储蓄 = $100 \times 10000 = 1,000,000$元 - 房价 = $2,000,000 \times 1.1 = 2,200,000$元 → **不足** 2. **第2年末**: - 储蓄 = $1,000,000 + 1,000,000 = 2,000,000$元 - 房价 = $2,200,000 \times 1.1 = 2,420,000$元 → **不足** 3. **第3年末**: - 储蓄 = $2,000,000 + 1,000,000 = 3,000,000$元 - 房价 = $2,420,000 \times 1.1 = 2,662,000$元 → **满足条件** ### 注意事项: 1. 房价在每年末计算增长后立即判断购房条件 2. 使用`sys.stdin`可处理文件重定向输入(如`python script.py < input.txt`) 3. 浮点数计算在题目参数范围内精度足够
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值