例題2-1 aabb(P20)
輸出所有形似aabb的4位完全平方數(shù)胁勺,下面這種方法不用開(kāi)根,如果使用開(kāi)根的方法圈驼,比如利用if(sqrt(n)==floor(sqrt(n)))
這種方法判斷是否是完全平方數(shù)捕儒,因?yàn)楦↑c(diǎn)數(shù)的計(jì)算存在誤差,所以要謹(jǐn)慎使用龙致,一般牽涉到浮點(diǎn)數(shù)的floor運(yùn)算蛀缝,都要進(jìn)行四舍五入,floor(x+0.5)
目代。
#include "stdafx.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
for(int i=0;;i++){
int x = i*i;
if(x<1000)continue;
if(x>9999)break;
int high = x / 100;
int low = x %100;
if(high/10==high%10 && low/10==low%10)
printf("%d\n",x);
}
return 0;
}
例題2-2 aabb(P23)
對(duì)于任意大于1的自然數(shù)n屈梁,若n為奇數(shù)嗤练,則n=3n+1,否則n=n/2在讶。經(jīng)過(guò)若干次這樣的變換煞抬,最終n一定會(huì)變?yōu)?。輸入n构哺,輸出變換次數(shù)此疹,n<=10^9。
我還在用VC6.0寫(xiě)程序遮婶,98年產(chǎn)生的VC6.0蝗碎,long long類(lèi)型是C99(1999年)中才新加的,所以并不支持旗扑,會(huì)報(bào)錯(cuò)蹦骑。而且VC6.0應(yīng)該是32位環(huán)境,所以用long也是不行的臀防。
16位系統(tǒng):long是4字節(jié)眠菇,int是2字節(jié)
32位系統(tǒng):long是4字節(jié),int是4字節(jié)
64位系統(tǒng):long是8字節(jié)袱衷,int是4字節(jié)
而__int64
(兩個(gè)下劃線(xiàn))則與long long
相同捎废,__int64
對(duì)應(yīng)I64d
,long long
對(duì)應(yīng)lld
// lt22.cpp : Defines the entry point for the console application.
// 3n+1問(wèn)題
#include "stdafx.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
__int64 n;
int count=0;
while(scanf("%I64d",&n)){
count=0;
while(1){
if(n==1)break;
if(n%2==1) n=3*n+1;
else n = n/2;
count++;
}
printf("%d\n",count);
}
return 0;
}
例題2-3 計(jì)算1-1/3+1/5-1/7+...,直到最后一項(xiàng)小于10^-6(P24)
// lt23.cpp : Defines the entry point for the console application.
//計(jì)算1-1/3+1/5-1/7+...直到最后一項(xiàng)小于10^-6
#include "stdafx.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
float x=1;
float sum=0;
int count=0;
do{
if(count%2==0){
sum+=x;
}
else if(count%2==1){
sum-=x;
}
count++;
x = 1.0/(2*count+1); //如果此處寫(xiě)成1/(2*count+1)結(jié)果將永遠(yuǎn)是1
}while(x>1e-6);
printf("%f\n",sum);
return 0;
}
例題2-4 階乘之和(P25)
輸入n,計(jì)算S=1!+2!+...+n!的末6位致燥。n<=10^6登疗。
陷阱就在階乘很容易就會(huì)產(chǎn)生乘法溢出,所以嫌蚤,有一個(gè)規(guī)律辐益。
要計(jì)算只包含加法,減法和乘法的整數(shù)表達(dá)式除以正整數(shù)n的余數(shù)脱吱,可以在每步計(jì)算之后對(duì)n取余智政,結(jié)果不變。
#include <stdio.h>
int main(int argc, char* argv[])
{
int n;
int sum=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int s=1;
for(int j=1;j<=i;j++){
s = (s*j%1000000);
}
sum = (sum+s)%1000000;
}
printf("%d\n",sum);
return 0;
}
習(xí)題2-2 韓信點(diǎn)兵
果斷暴力循環(huán)求解
#include <stdio.h>
int main(int argc, char* argv[])
{
int a,b,c;
int count=0;
while(scanf("%d%d%d",&a,&b,&c)==3){
count++;
for(int i=10;i<=100;i++){
if(i%3==a && i%5==b && i%7==c){
printf("Case %d: %d",count,i);
break;
}
}
if(i==101)printf("Case %d: No answer",count);
}
return 0;
}
習(xí)題2-4 子序列之和
本題陷阱兩處箱蝠。首先要在代碼中將被除數(shù)1寫(xiě)成浮點(diǎn)形式1.0续捂,第二正整數(shù)的平方有可能會(huì)導(dǎo)致溢出,所以不能直接使用1.0/(m*m),要改成1.0/m/m,才沒(méi)有問(wèn)題宦搬。
#include <stdio.h>
int main(int argc, char* argv[])
{
int n,m;
int count=0;
double sum=0;
while(scanf("%d%d",&n,&m)&&(n||m)){
sum=0;
count++;
for(int i=n;i<=m;i++){
sum += 1.0/i/i;
}
printf("Case %d: %.5lf\n",count,sum);
}
return 0;
}
習(xí)題2-5 分?jǐn)?shù)化小數(shù)
本題說(shuō)要精確到小數(shù)點(diǎn)后c位牙瓢,由于之前認(rèn)為printf("%5.3f",x)
中的‘5’和‘3’都只能是常數(shù)而不能是變量,所以曾嘗試將a/b的結(jié)果乘以10的c次方再除以10的c次方床三,利用%g出去之后多余的零一罩,但其實(shí)并不符合題意。后來(lái)了解到其中是可以有變量的撇簿,比如printf("%*.*lf",x,y,z)
其中的第一個(gè)*對(duì)應(yīng)后面的x聂渊,代表整個(gè)數(shù)輸出寬度,第二個(gè)*對(duì)應(yīng)后面的y四瘫,代表小數(shù)點(diǎn)后保留位數(shù)汉嗽,而要輸出的數(shù)是z。
#include <stdio.h>
int main(int argc, char* argv[])
{
int a,b,c;
int count=0;
while(scanf("%d%d%d",&a,&b,&c)&&(a+b+c)){
count++;
double ans = (double)a/(double)b;
printf("Case %d: %.*lf\n",count,c,ans);
}
return 0;
}
習(xí)題2-6 排列
暴力求解相當(dāng)麻煩找蜜。所以設(shè)置數(shù)組饼暑,看最后數(shù)組和是否為9。很巧妙洗做。
#include <stdio.h>
int main(int argc, char* argv[])
{
int x,y,z;
int a[10]={0};
for(x=100;x<330;x++){
y = x*2;
z = x*3;
a[x/100] = a[x/10%10] = a[x%10] = 1;
a[y/100] = a[y/10%10] = a[y%10] = 1;
a[z/100] = a[z/10%10] = a[z%10] = 1;
int sum=0;
for(int i=1;i<=9;i++){
sum += a[i];
}
if(sum==9)
printf("%d %d %d\n",x,y,z);
for(i=0;i<=9;i++){
a[i]=0;
}
}
return 0;
}
思考題 題目2
#include <stdio.h>
int main(int argc, char* argv[])
{
double i;
for(i=0;i!=10&&i<11;i+=0.1){
printf("%.1f\n",i);
}
return 0;
}
由上面代碼輸出結(jié)果看不出到底為什么會(huì)出現(xiàn)一直循環(huán)輸出的錯(cuò)誤弓叛。
但其實(shí)是因?yàn)檠h(huán)中是浮點(diǎn)數(shù)運(yùn)算,浮點(diǎn)數(shù)在計(jì)算機(jī)中采用二進(jìn)制科學(xué)計(jì)數(shù)法來(lái)儲(chǔ)存诚纸,絕大多數(shù)是不能精確表示的撰筷。
當(dāng)兩個(gè)浮點(diǎn)數(shù)都是由賦值得到的,如
a=3.3;
b=3.3;
則a==b值為真畦徘。
而當(dāng)a毕籽,b中至少有一個(gè)為經(jīng)由運(yùn)算得到,那么由于其精確度的原因井辆,會(huì)出現(xiàn)這樣的情況
a=1.7+2.7;
b=4.4;
則a==b的值就不一定為真了关筒。
若想進(jìn)行粗略的比較,則可用
fabs(a-b)<1e-6
floor(b+0.5)==floor(a+0.5)
等限制誤差的語(yǔ)句杯缺。