1. 程式人生 > >C語言總複習

C語言總複習

                  problem 1

簡要題意
爬樓梯,每次跨一級或兩級,要走上M級,共多少種走法? 輸入一個整數n,表示測試個數,然後是n行資料,每行包含一個整數M,表示樓梯階數 輸出每組測試資料的不同走法的數量
解題思路 爬樓梯的爬法數目符合斐波那契數列,可以這樣想:設S(n)表示走n級臺階的走法數量。走n級臺階,第一步只有兩種選擇:可以選擇走1階,然後還有S(n-1)種走法;選擇走2階,那麼接下來有S(n-2)種走法。那麼S(n) = S(n-1) + S(n-2)。
解題細節 注意剛開始時我準備用比較普通的方法解題,但每次都超時,這題的關鍵就是找到規律。原始碼: #include
using namespace std;
int num;
long long DP[51];
long long dp(int n)
{
DP[0]=0;
DP[1]=1;
DP[2]=2;
for(int i=3;i<=n;i++)
{
DP[i] = DP[i-1]+DP[i-2];
}
return DP[n];
}
int main()
{ cin>>num;
cout<<dp(num)<<endl;
return 0;}
總結一下,這道題其實真正實現起來不難,每個人都能用C++編寫出斐波那契數列從而得到正確的值,但是問題在於能否發現這是一道斐波那契數列題。 problem 2
簡要題意
有如下方程:Ai = (Ai-1 + Ai+1)/2 - Ci (i = 1, 2, 3, … n).若給出A0, An+1, 和 C1, C2, …Cn.請程式設計計算A1 = ?
解題思路:
這是一道數學規律題,通過多算幾組資料找到其中的規律 可由已經給出的函式,推匯出 n=3;4A1=3A0+A4-6C1-4C2-2C3 n=2;3A1=2A0+A3-4C1-2C2 n=1;2A1=A0+A2-2C1故當n=k時,(k+1)A1=k

A0-2(kC1+(k-1)C2+…+Ck)然後得到A1的表示式
解題細節:
注意結尾需要保留兩位小數,相對於用cout輸出,printf在這時顯得更簡單原始碼:
#include
#define N 3000+10
double c[N], d[N];
using namespace std;
int main()
{ int n;
double af, al, A=0.0;
while(cin>>n)
{
double a=0.0;
cin>>af>>al;
a=n
af+al;
for(int i=1,j=n;i<=n;i++,j–)
{ cin>>c[i];
d[i]=2
c[i];
a-=jd[i];
}
A=a/(n+1);
printf("%.2lf\n",A); }
return 0;}
總結:這道題在剛開始做時,真是一點思路都沒有,但當真做完後,就覺著這道題其實也沒啥,關鍵就是找到其中隱藏的規律,因此在做題時要有足夠的耐心,認真讀好題,才不至於一遍又一遍地錯。
problem 3
簡要題意 對於表示式n^2+n+41,當n在(x,y)範圍內取整數值時(包括x,y)(-39<=x<y<=50),判定該表示式的值是否都為素數。輸入資料有多組,每組佔一行,由兩個整數x,y組成,當x=0,y=0時,表示輸入結束,該行不做處理
解題思路 這個題完全可以用老師上課講的判定素數的函式,用此方法解題很簡單,但我也因為不經常使用函式,在提交時錯了很多遍。
解題細節 在解題時千萬不要漏掉表示式等於1時的特殊情況,我就是因為漏掉了它,總是通不過。
原始碼:
#include
#include
using namespace std;
int prime(int x)
{ int i,n;
n=sqrt(x);
for(i=2;i<=n;i++)
{ if(x%i0) return 0; }
return 1;}
int main(){
int x,y,i,j,p,a[100];
while(cin>>x>>y)
{ p=0,j=0;
if(x
0&&y==0) break;
for(i=x;i<=y;i++)
{ j++;
a[j]=i
i+i+41;
}
for(j=1;j<=y-x+1;j++)
{
if(prime(a[j])&&a[j]!=1) p++;
}
if(py-x+1) cout<<“OK”<<endl;
else cout<<“Sorry”<<endl;}}
總結:在編寫程式時,用一些自定義的函式可以使自己的程式碼看起來更整潔,並且更好理解,同時,在寫程式碼時,各種條件一定要考慮周全。
problem 4
簡要題意: 水仙花數是指一個 n 位數(n≥3 ),它的每個位上的數字的 n 次冪之和等於它本身(例如:1^3 + 5^3+ 3^3 = 153,現求n到m區間內所有水仙花數
解題思路: 通過迴圈,將區間n到m內的水仙花數全部存入陣列內,待迴圈完畢後,判斷陣列內的數,若為0,則輸出no,否則輸出yes
解題細節: 在輸入n,m時,先輸入n,後輸入m.輸出水仙花數時要求從小到大,且有空格
原始碼:
#include
using namespace std;
int main(){
int x[1010];
int i,j=0,k=0,n,m,a=0,d=0;
while(cin>>n>>m)
{ d=0;
for(i=n;i<=m;i++)
{ a=i/100;
j=(i%100)/10;
k=i%10;
if(a100+j10+k
aaa+jjj+kkk)
{ x[d++]=i;
} }
if(d0) cout<<“no”<<endl;
else {
for(i=0;i<d;i++) {
if(i!=d-1) cout<<x[i]<<" ";
else cout<<x[i]<<endl; } } }return 0;}
總結:在寫程式碼時注意審題,剛開始交時,我就是因為n與m輸反了,導致了wa,因此在以後寫程式碼時,一定注意審題。
problem 5
簡要題意: 求出a到b之間不含有連續的62 不含有4的數的個數
解題思路: 先將從1到100000之間所有的含有連續62和4的數全部記錄,即進行預處理,將資料存入陣列中,然後輸入n,m便可以直接從中找到不合理的數,最後用所有的牌號減去不合理的牌號即為所求。
解題細節: 在最後輸出時區間n,m間車牌個數是m-n+1個。
原始碼:
#include
#define M 1000000+10
using namespace std;
int a[M];int main()
{ int n, m, c=0;
for(int i=1;i<=1000000;i++)
{ int z=i, q;
while(z)
{ q=z%10;
z=z/10;
if(q
4)
{ c++;
break; }
else if((q2)&&(z%106))
{ c++;
break; } }
a[i]=c; }
while(cin>>n>>m) {
if(n0&&m0) break;
else
cout<<m-n+1-(a[m]-a[n-1])<<endl; }
return 0;}
problem 6
簡要題意:有n(n<=100)個整數,已經按照從小到大順序排列好,現在另外給一個整數x,請將該數插入到序列中,並使新的序列仍然有序。
解題思路:將原來的陣列輸進後,開始用m進行比較,若m大於a[n-1]則a[n]=m,否則再將m與a[n-2]進行比較,依次比較後便將m插入陣列,最後輸出新的陣列
解題細節: 在插入m後要注意將m後的數依次移位
原始碼:
#include
using namespace std;
int main()
{ int i,n,m,s[1007];
while(cin>>n>>m)
{ if(m0&&n0) break;
for(i=0;i<n;i++)
cin>>s[i];
if(m>s[n-1])
s[n]=m;
else
{ i–;
while(s[i]>m)
{
s[i+1]=s[i];
i–; }
s[i+1]=m; }
for(i=0;i<=n;i++){
printf("%d",s[i]);
if(i<n) printf(" “);
else printf(”\n"); } }
return 0;}
problem 7
簡要題意: 多項式的描述如下: 1 - 1/2 + 1/3 - 1/4 + 1/5 - 1/6 + … 現在請你求出該多項式的前n項的和。輸入資料由2行組成,首先是一個正整數m(m<100),表示測試例項的個數,第二行包含m個正整數,對於每一個整數(不妨設為n,n<1000),求該多項式的前n項的和對於每個測試例項n,要求輸出多項式前n項的和。每個測試例項的輸出佔一行,結果保留2位小數
解題思路: 首先觀察到多項式奇數項偶數項的符號不同,因此需要進行分類,偶數項前面加負號,剩下的就交給迴圈進行
解題細節: 測試資料結果保留兩位小數,因此在定義時可用double,我在最開始時沒有注意以至於輸出的結果全是1
原始碼
#include
using namespace std;
int main()
{ int i,a,n;
cin>>a;
while(a!=0)
{ a–;
cin>>n;
double m=0,p=0;
double sum;
for(i=1;i<=n;i++)
{
if(i%2!=0) m=m+(1.00/i);
if(i%2==0) p=p+((-1.00)/i); }
sum=m+p;
printf("%.2f\n",sum); }}
總結:在出現除法時,要注意帶餘除法對結果是否有影響。
problem 8
簡要題意:求A^B的最後三位數表示的整數
解題思路: 既然是求最後三位數表示的整數,就對該數進行求餘,且是三位數的求餘,由於題中給的數範圍較大,不可能把他求出來,因此這種方法較為簡單
解題細節:不能將A直接算出,因為有些A^B的範圍超過了64位整型數
原始碼:
#include
using namespace std;
int main()
{ int i,a,b,c;
while(cin>>a>>b&&(a!=0||b!=0))
{ a%=1000;
c=1;
for(i=1;i<=b;i++)
{ c=c*a%1000; }
cout<<c<<endl; }}
problem 9
簡要題意:設有一頭小母牛,從出生第四年起每年生一頭小母牛,按此規律,第N年時有幾頭母牛,本題有多組資料。每組資料只有一個整數N,獨佔一行。(1≤N≤50)。當N為0時,輸入結束。
解題思路: 我們只分析n>=4的情況,因為前三年只有1。我們可以設f(i)為第i年母牛的數量,那麼f(i)怎麼算,我們知道第i年牛的數量肯定等於上一年牛的數量加上第i年新生的牛。因為牛到第四年就可以生小牛,所以到第i年可以生小牛的牛的數量為f(i-3)。所以f(i)=f(i-1)+f(i-3),遞推公式出來了,程式碼很簡單。
解題細節: 類似與斐波那契數列,長度由3變為4,則f(n) = f(n-1) + f(n-3)
原始碼:
#include
using namespace std;
int main()
{ int f[50],i,n;
while(cin>>n&&n!=0)
{ f[1]=1;f[2]=2;f[3]=3;
for(i=4; i<=n;i++)
{ f[i]=f[i-3]+f[i-1]; }
cout<<f[n]<<endl; }
return 0;}
總結;在此次作業中有很多這種找規律型別的題,用到裴波那切數列的題目不在少數,在分析題目時,注意找規律時多向這方面靠攏。
problem 10
簡要題意: 在平面內有兩個點,求兩個點分別和原點的連線的夾腳的大小,輸出夾腳大小精確到小數點後兩位
解題思路: 使用數學公式向量表示式求出cos x 最後輸出時使用反三角函式輸出
解題細節: 在正常運算時,其中的圓括號個數很多,注意區分。使用的反三角函式與實際的不同,應為acos x

原始碼:
#include
#include
#define PI
acos(-1)int main()
{ int u; double x1,x2,y1,y2;
double ans;
scanf ("%d",&u); while (u–)
{ scanf ("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
ans = (x1 * x2 + y1 * y2) / (sqrt(x1x1+y1y1) *
sqrt(x2x2 + y2y2));
ans = acos(ans) * 180 / PI;
printf ("%.2lf\n",ans); }
return 0;}
總結:這是第一次見到使用反三角函式的程式碼,一定要記住哦!
problem 11
簡要題意:一個整數,只知道前幾位,不知道末二位,被另一個整數除盡了,那麼該數的末二位該是什麼。
解題思路: 第一個數乘一百,然後進行迴圈,每次加一,當迴圈到某次,對第二個數求餘為零時,輸出迴圈次數,即尾數。
解題細節: 注意輸出時控制空格,還有,十位上為0的要補0。
原始碼:
#include<stdio.h>
int main( )
{ int a,b,i,flag;
while(scanf("%d%d",&a,&b),a&&b)
{ flag=0; for(i=0;i<100;i++)
{ if((a100+i)%b0)
{ if(flag
0)
{ flag=1;
printf("%02d",i); }
else
printf("% 02d",i); } }
printf("\n"); }
return 0;}
problem 12
簡要題意:把一個偶數拆成兩個不同素數的和,算有幾種拆法
解題思路: 在開頭寫一個判斷素數的函式備用,在主函式內對輸入的n進行拆分,分為i,n-i,然後用判斷素數的函式進行判斷,最後輸出個數。
解題細節: 注意1既不是素數也不是合數,在開始寫時,我姐因為沒注意這一點錯了好長時間
原始碼:
#include
#include
using namespace std;
bool pri(int k)
{ int i;
for(i=2;i<=sqrt(k);i++)
if(k%i0) break;
if(i>sqrt(k)) return 1;
return 0;}
int main()
{ int n;
while(cin>>n,n)
{ int count=0;
for(int k=2;k<n/2;k++)
if(pri(k)&&pri(n-k))
count++;
cout<<count<<endl; }
return 0;}
problem 13
簡要題意: 判斷一個數十進位制數字相加是否等於十六進位制和十二進位制數字相加,若是輸出n is a Sky Number. 否則輸出 n is not a Sky Number.
解題思路: 先自定義一個函式 用來計算轉換後每一位的數,在主函式內便只需判斷三種轉換後數字加起來是否相等即可
解題細節: 在輸出 is a Sky Number.時,不要忘了最後的句號
原始碼:
#include <stdio.h>
#include <stdlib.h>
int g(int m,int n)
{ int sum=0;
while(m)
{ sum+=m%n;
m=m/n; }
return sum;}
int main()
{ int n,a,b,c;
while(~scanf("%d",&n)&&n)
{ a=g(n,10);
b=g(n,12);
c=g(n,16);
if(a
b&&b==c)
printf("%d is a Sky Number.\n",n);
else printf("%d is not a Sky Number.\n",n); }
return 0;}
problem 14
簡要題意: 有二個整數,它們加起來等於某個整數,乘起來又等於另一個整數,它們到底是真還是假
解題思路: 由x+y=n,x
y=m可推知x,y為某方程的根,我們可以通過根與係數的關係來做這道題,又因為根是整數,這需要sqrt()是整數,由此得到以下程式碼
解題細節: 在輸出時注意Yes No均為首字母大寫
原始碼:
# include
# include
using namespace std;
int main()
{ int n,m;
int t;
while(cin>>n>>m,n!=0||m!=0)
{ int num = nn - 4m;
t = sqrt(num);
if(tt==num)
{ cout<<“Yes”<<endl; }
else
{ cout<<“No”<<endl; } }
return 0;}
problem 15
簡要題意: 把一個字元三角形掏空,每行包含一個字元和一個整數n(0<N<41),不同的字元表示不同的花紋,整數N表示等腰三角形的高。顯然其底邊長為2N-1。如果遇到@字元,則表示所做出來的樣板三角形已經夠了。 每個樣板三角形之間應空上一行,三角形的中間為空。顯然行末沒有多餘的空格。
解題思路: 找規律題!首先要考慮到前n-1排和第n排不一樣,第n排全部輸出(總共2
n-1個字元),而前n-1排需要找規律:第一個字元所在的位置為n-(i-1),(其中i代表的是第i行);而第二個字元所在的位置是n+(i-1);(注意:最後一個字元後面沒有空格!),除下這兩個位置在小於等於n+(i-1)的位置上全是空格!
解題細節: 在輸出第二個三角形時,注意它與上邊的數空了一行。
原始碼:
#include
#include
using namespace std;
int main()
{ char c;
int n;
int flag=0;
while(cin>>c)
{ if(c==’@’) break;
cin>>n;
if(flag) cout<<endl;
flag=1;
if(n==1) cout<<c<<endl;
else {
cout<<string(n-1,’ ‘)<<c<<endl;
for(int i=1;i<n-1;i++) {
cout<<string(n-i-1,’ ')<<c;
cout<<string(2i-1,’ ')<<c<<endl; }
for(int i=0;i<2
n-1;i++) cout<<c;
cout<<endl;
}getchar();
}return 0;}
總結:在做這道題時,沒有注意到在輸出第二個三角形時需要空行,因為這個原因,交了好多遍,只能說,認真審題啊!
總結:經過對c語言一個學期的學習,從最初的最基本的順序迴圈到後來越來越複雜的陣列訓練。程式設計讓我看到了一個豐富多彩的資訊世界。從最初的hello world,到後來解決越來越多的實際問題,這讓我切實感到資訊科技對我們實際生活的影響。雖然我們只接觸了一個學期的C語言,但通過這段時間的學習,我從最初的抵觸,到後來慢慢接受,程式帶給我的不僅僅是解決問題的方法,更是在解決過程中逐步探索問題時候的感覺。
剛開始學的時候總感覺力不從心,到後來程式寫多了也就適應了。C語言不是想象中那麼枯燥無味,相反它是一門多彩的有趣的學科,對一道題目你可以有多種解法,在尋找方法過程中,各種思想,各種做法相互碰撞,最終尋到最合適的那一個,但寫出程式並不意味著你的程式就是對的,這還需要你堅持不懈地去除錯程式,可能一個小小的錯誤會讓你除錯一兩個小時,這使得你便需要有足夠的耐心去實驗,去變通你的程式碼。