| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1371 人关注过本帖
标题:终于。。。学有所用了。。。。
只看楼主 加入收藏
smltq
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:566
专家分:400
注 册:2008-1-21
收藏
得分:0 
[bo][un]中学者[/un] 在 2008-10-2 20:46 的发言:[/bo]

我惭愧自己一直停留在初级群
现在QQ也不用了....潜心学习



在CF吧
2008-10-03 20:03
中学者
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:20
帖 子:3554
专家分:80
注 册:2007-9-14
收藏
得分:0 
回复 11# smltq 的帖子
很可疑...你是谁?报上名来!

樱花大战,  有爱.
2008-10-03 22:09
wangweinoo1
Rank: 1
等 级:新手上路
帖 子:67
专家分:0
注 册:2008-9-7
收藏
得分:0 
[bo][un]qGemini[/un] 在 2008-10-2 16:30 的发言:[/bo]

楼主,你这程序很不好,请参考上的教学区的一篇基础文章



嗯嗯,我也感觉到了。。。代码太长,效率低。。。
不过你不贴出来具体地址也太坑人了吧。。。
俺找了N长时间。。。
2008-10-05 13:54
wangweinoo1
Rank: 1
等 级:新手上路
帖 子:67
专家分:0
注 册:2008-9-7
收藏
得分:0 
[bo][un]StarWing83[/un] 在 2008-10-3 11:52 的发言:[/bo]

那篇文章我找不到了……麻烦给个链接?


哦哈哈,经过我的反复查找,居然找到了这篇传说中的神秘帖子。。。

算法技巧小集合(C语言描述)
1.例题ct3_1: 个人所得税计算★
(源自 [url=http://]http://[/url] )
题目描述:
个人所得税计算方法:假设起征点为k元,
超过k到k+500这部分税率为0.05
超过k+500到k+2000这部分税率为0.1
超过k+2000到k+5000这部分税率为0.15
超过k+5000到k+20000这部分税率为0.2
超过k+20000到k+40000这部分税率为0.25
超过k+40000到k+60000这部分税率为0.3
超过k+60000到k+80000这部分税率为0.35
超过k+80000到k+100000这部分税率为0.4
超过k+100000的部分的税率为0.45

输入:
多组测试数据,每组一行,一行有两个整数n和k
n是收入,0<= k,n <= 2e9
当输入0 0的时候结束

输出:
输出要交的税的数额,保留2位小数

样例输入:
800 800
1000 800
2000 1000
0 0

样例输出:
0.00
10.00
75.00

题目看似很复杂,因为数据分段明显不少,并且看似没有关联。
从原题目的链接帖子的第一页里,你可以看到很多人写了N多if嵌套,
程序逻辑显得极其混乱,并且非常容易出错,
只要看他们提交的结果都不对就知道了。
如果是你,你会怎么写这一题的解答代码呢?
不妨在看后面解答之前先细心想想,等你想尽办法以后,
再看看以下的解答,也许那种恍然大悟的感觉会非常好哦!
以下先帖一段经典if嵌套的方法并且能通过的C代码:

程序代码:
#include <stdio.h>
int main(void)
{
    int k,n;
    while (scanf("%d%d",&n,&k),!(n==0&&k==0))//数据输入
    {
        double tax = 0.0;
        if( n-k <= 0 ); //使用分段函数方式计算
        else if ( n-k-500 < 0 )
            tax = (n-k)*0.05;
        else if( n-k-2000 < 0 )
            tax = 500*0.05 + (n-k-500)*0.1;
        else if ( n-k-5000 < 0)
            tax = 500*0.05 + (2000-500)*0.1 + (-2000+n-k)*0.15;
        else if ( n-k-20000 < 0)
            tax = 500*0.05 + (2000-500)*0.1 + (5000-2000)*0.15
                +(n-k-5000)*0.2;
        else if ( n-k-40000 < 0)
            tax = 500*0.05 + (2000-500)*0.1 + (5000-2000)*0.15
                +(20000-5000)*0.2 +(k-n-20000)*0.25;
        else if ( n-k-60000 < 0)
            tax = 500*0.05 + (2000-500)*0.1 + (5000-2000)*0.15
                +(20000-5000)*0.2+(40000-20000)*0.25+(n-k-40000)*0.3;
        else if ( n-k-80000 < 0)
            tax = 500*0.05 + (2000-500)*0.1 + (5000-2000)*0.15
                +(20000-5000)*0.2+(40000-20000)*0.25+(60000-40000)*0.3
                +(n-k-60000)*0.35;
        else if ( n-k-100000 < 0)
            tax = 500*0.05 + (2000-500)*0.1 + (5000-2000)*0.15
                +(20000-5000)*0.2+(40000-20000)*0.25+(60000-40000)*0.3
                +(80000-60000)*0.35+(n-k-80000)*0.4;
        else 
            tax = 500*0.05 + (2000-500)*0.1 + (5000-2000)*0.15
                +(20000-5000)*0.2+(40000-20000)*0.25+(60000-40000)*0.3
                +(80000-60000)*0.35+(100000-80000)*0.4+(n-k-100000)*0.45;
        printf("%.2lf\n",tax); //输出计算结果
    }
    return 0;
}
首先要声明,帖此代码并不是给大家取笑,而事实上,面对这个题目,
很多初学者的确就是使用类似以上代码的变形(帖子里还有比这个更长的),
但偶认为他(她)们也的确思考过,只是实在觉得没有办法化简了。
偶也曾经见过有人写一个解24点游戏的程序,24点游戏就是给你四个数,
通过加入四则运算符和括号,使得表达式的值为24。
这个解24点游戏的程序需要全排列和运算符和括号穷举,对于初学者的确不容易。
那个人也挺“聪明”的,他知道四个数的排列不过24种,
三个符号的排列不过4^3=64种,括号不过5种,最多也不过24*64*5=7680种,
当中一些重复的,去掉后大约二三千种,于是他一种写一个if,
最后代码写了六七千行,也的确顺利地解决了。
这种方法也不失为一种算法,或者可以称为源代码级别穷举算法吧。
偶看到那个程序的代码的时候,不得不Orz程序作者的毅力。
但是,我们为什么要学算法?这个题目就回答了这个问题的一个方面:
好的算法可以让你的代码更清晰明了,更简短优美,
还有在代码有问题的时候也能够更容易发现错误的地方。

现在不讲那个24点,转回这个题目。你现在想到好办法了没有?
我们来简单一点,先考虑收n<=5000元,k=0的情况,有如下信息:
超过k到k+500这部分税率为0.05
超过k+500到k+2000这部分税率为0.1
超过k+2000到k+5000这部分税率为0.15
其实我们完全可以不要按照字面的逻辑来进行程序的分界,
我们可以把它们打乱。比如,
k+500到k+2000这部分,相当于征收两次税,且均为0.05
k+2000到k+5000这部分,相当于征收三次税,且均为0.05
那么原题目等价地换为:
超过k这部分需征收一次,税率为0.05
超过k+500这部分需再次征收,税率为0.05
超过k+2000这部分需再次征收,税率为0.05
结果全部均变为0.05,很合理地,我们想到循环,重复地做同一个东西。
于是,你现在再想想,还需要不需要写那么多的if语句呢?
并且if写得越多、写得越复杂就算容易错。我们需要一段简短漂亮的代码。
相信说到这里,您也差不多甚至已经想到解决办法了。
如果你已经想到了,那恭喜你!!!

以下为标准解答程序(下文简称“标程”),请细心阅读:
程序代码:
// http:// <stdio.h>
int main()
{
    int n,k,t;
    unsigned nBase[]={0,500,2000,5000,20000,
        40000,60000,80000,100000,-1};
    while(scanf("%d%d", &n, &k), n>0||k>0) //数据输入
    {
        double sum = 0;
        for(n-=k,t=0; (unsigned)n>nBase[t]; ++t)
        {
            sum += n - nBase[t];
        }
        printf("%.2lf\n", sum/20.0); //输出计算结果
    }
    return 0;
}

而事实上,你可能会问,是不是那个税率等间距递增才能使用这种方法。
那偶告诉你,其实不等间距递增也没有问题的,甚至递增和递减混合也行,
一样可以使用此办法化简得如上仅10行左右代码,并且可扩展性可以很好。
这个就留给读者您自己思考一下吧。

// ************************************************************ //
// 本文源自飞燕之家在线测评论坛http://,转载清注明出处 //
// ************************************************************ //
2008-10-05 14:00
快速回复:终于。。。学有所用了。。。。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018306 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved