一、for循環
1.1? for 循環語法形式
for 循環是三種循環中使用最多的 , for 循環的語法形式如下:
1.2 執行流程
for 循環中 , 表達式1(初始化)只執行一次 !
1.3 實踐
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int i = 0;for(i = 1;i<=10;i++){cout << i << " ";}return 0;
}
1.4 while 和 for 對比
for 和 while 在實現循環的過程中都有初始化 、 判斷 、 調整這三個部分 , 但是 for 循環的三個部分非常集中 , 便于代碼的維護 , 而如果代碼較多的時候 while 循環的三個部分就比較分散 , 所以 從形式上 for 循環要更優一些 。?
1.5 練習
練習一 : 求和2
計算1~100之間3的倍數的數字之和思路 :1 . 產生 1 ~100 的所有數字 --> for2 . 判斷是否是 3 的倍數? ------> if(i % 3 == 0)3 . 如果是3的倍數,就求和 ---> sum +=i
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int i = 0;int sum = 0;for(i = 1 ;i<=100 ; i++){if(i % 3 == 0)sum += i;}cout << sum << endl;return 0;
}
如果直接產生3的倍數 的數字 就省去了多余的循環和判斷?
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int i = 0;int sum = 0;for(i = 3 ;i<=100 ; i+= 3){sum += i;}cout << sum << endl;return 0;
}
兩個方法相比 , 第二個較優一些 , 執行的次數比代碼一少!?
練習二 : 求平均年齡
B2054 求平均年齡 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int n = 0;cin >> n;int age = 0;int sum = 0;for(int i = 1 ;i <= n ; i++){cin >> age;sum += age;}printf("%.2lf\n",sum*1.0/n);return 0;
}
練習三 : 奧運獎牌計數
B2058 奧運獎牌計數 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;int a, b , c ;//每一天的獎牌數
int p1, p2, p3;
int sum;
int main()
{int n = 0;cin >> n;for(int i = 1 ; i<= n ; i++){//讀取每一天的獎牌數cin >> a >> b >> c;p1 += a;p2 += b;p3 += c;} sum = p1 + p2 + p3;cout << p1 << " " << p2 << " " << p3 << " " << sum << endl;return 0;
}
練習四 : 雞尾酒療法
B2065 雞尾酒療法 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;int a,b; //a:總病例數 b:有效病例數
float x,y; //x:雞尾酒療法有效率 y:改進后的
int main()
{int n = 0;//1.輸入n cin >> n;//2.讀取第一組數據 cin >> a >> b;x = b*1.0 / a;//3.讀取 n - 1 組的對照組數據for(int i = 1;i <= n-1 ; i++){cin >> a >> b;y = b * 1.0 / a;if(y - x > 0.05)cout << "better" << endl;else if(x - y > 0.05)cout << "worse" << endl;elsecout << "same" << endl; } return 0;
}
練習五 :救援
B2066 救援 - 洛谷
在解決問題之前 , 先了解一下兩個庫函數ceil 和 floor 函數 :?
ceil : 對于一個浮點數向上取整 , 需要頭文件 <cmath>
ceil - C++ Reference
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;int main()
{cout << ceil(2.3) << endl;cout << ceil(3.8) << endl; cout << ceil(-2.3) << endl;cout << ceil(-3.8) << endl;return 0;
}
floor : 對一個浮點數向下取整 , 需要頭文件 <cmath>
floor - C++ Reference
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;int main()
{cout << floor(2.3) << endl;cout << floor(3.8) << endl; cout << floor(-2.3) << endl;cout << floor(-3.8) << endl;return 0;
}
解題思路:
1 . 輸入n
2. 循環 n 次
? ? ? ? ? ?每次處理一個屋頂 (計算舉例,計算時間,時間累加)
3. 輸出時間 --> 向上取整
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;int p;
int n;
double x,y;
int main()
{cin >> n;double t = 0;for(int i = 0 ; i< n ;i++){cin >> x >> y >> p;float dis = sqrt(x*x + y*y);t += p*1 + dis/50 + p*0.5 + dis/50;}cout << (int)ceil(t) << endl;return 0;
}
練習六 :計算分數加減表達式的值
B2070 計算分數加減表達式的值 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int n = 0;double sn = 0;int flag = 1;cin >> n;for(int i = 1;i<=n ; i++){sn += flag * 1.0 / i;flag = -flag;}printf("%.4f\n",sn);return 0;
}
還可以使用庫函數 pow 函數 ---> pow(x,y) ,x的y次方 , 需要包含頭文件<cmath>?
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;int main()
{int n = 0;double sn = 0;cin >> n;for(int i = 1;i<=n ; i++){sn += pow(-1,i-1) * 1.0 / i;}printf("%.4f\n",sn);return 0;
}
?還有一種方法 , 可以通過判斷奇偶? 來決定 sn是+= 還是-=
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;int main()
{int n = 0;double sn = 0;cin >> n;for(int i = 1;i<=n ; i++){if(i%2)sn += 1.0 / i;elsesn -= 1.0 / i; }printf("%.4f\n",sn);return 0;
}
練習七 :求分數序列和
B2069 求分數序列和 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int n;double sum = 0;double p = 1;double q = 2;cin >> n;for(int i = 1 ; i<=n;i++){//1.產生1項 累計求和 sum += q / p;//2.為下一項準備 p 和 qq = q + p; p = q - p;}printf("%.4lf\n",sum);return 0;
}
二、do-while 循環
2.1 do-while語法形式
在循環語句中 , do while 語句的使用最少 , 它的語法如下 :?
?1.?while 和 for 這兩種循環都是先判斷,條件如果滿足就進入循環,執行循環語句,如果不滿足就跳 出循環;
2. do while 循環則是 先直接進入循環體,執行循環語句 ,然后再執行? while 后的判斷表達式,表達式為真,就會進行下?次,表達式為假,則不再繼續循環。
2.2 執行流程
2.3 實踐
使用?do while 循環在屏幕上打印1~10的值
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int i = 1;do{cout << i << " ";i++;}while(i <= 10);return 0;
}
2.4 練習
練習一 : 統計正整數的位數
輸入一個正整數,計算這個整數是幾位數?例如:輸入:1234 輸出:4輸入:12 輸出:2
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int n = 0;cin >> n;int c = 0;do{c++;n/=10;}while(n);cout << c << endl;return 0;
}
這里并非必須使用 do while 語句 , 但是這個代碼就比較適合使用 do while 循環 , 因為即使 n 是 0 , 也是 1 位數 , 需要統計位數。
以上的代碼 , c 每 ++ , n 就刪掉一位數(n % 10)?
練習二 :球彈跳高度的計算
B2076 球彈跳高度的計算 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;int main()
{double h;cin >> h;double sum = h;int i = 1;do{h/=2;sum += 2*h;i++;}while(i<=9);cout << sum << endl;cout << h/2 << endl;return 0;
}
三 、break 和 continue 語句
3.1 break 和 continue 介紹
1 . 在循環執行的過程中 , 如果某些狀況發生的時候 , 需要提前終止循環 , 這是非常常見的現象 。 C++ 中提供了break 和 continue 兩個關鍵字 ,就是應該到循環中 。
2 . break 的作用是用于永久的終止循環 , 只要break 被執行 , 直接就會跳出循環 , 繼續往后執行 。
3 . continue 的作用是跳出本次循環 continue 后邊的代碼 , 在 for 循環和 while 循環中 有所差異 。
4 . 注意break 和 continue 在各循環語句中的使用方式基本相同 , 這里僅以while 循環舉例。?
3.2 break 舉例
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int i = 1;while(i <= 10){if(i == 5)break;cout << i << " ";i++;}return 0;
}
3.3 continue 舉例
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int i = 1;while(i <= 10){if(i == 5)continue;cout << i << " ";i++;}return 0;
}
如果在for 循環中使用continue 呢 ?
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int i = 0;for(i = 1;i<=10 ; i++){if(i == 5)continue;cout<< i << " ";}return 0;
}
這時候的 continue 在 while 循環和 for 循環中略有差異!!!
3.4 練習:質因數分解
B2084 質因數分解 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int n;cin >> n;for(int i = 2;i < n ; i++){//找能整除的最小因數 if(n % i == 0){cout << n / i << endl;break;}}return 0;
}
四、循環嵌套
4.1 循環嵌套的使用
前面我們學習了三種循環 : while , do while , for , 這三種循環往往會嵌套在一起才能更好解決問題 , 就是我們所說的 : 循環嵌套 。 這三種循環都可以任意嵌套使用 。
?比如 : 打印一個乘法口訣表
觀察后 : 我們發現 每一項就是 ---> 列 * 行 = 乘積
#include <iostream>
#include <cstdio>
using namespace std;int main()
{for(int i = 1;i <=9 ; i++){for(int j = 1 ; j <= i ;j++){printf("%d*%d=%2d ",i,j,i*j);}printf("\n");}return 0;
}
4.2 練習
練習一:乘法表
登錄—專業IT筆試面試備考平臺_牛客網
#include <iostream>
#include <cstdio>
using namespace std;int main()
{for(int i = 1;i <=9 ; i++){for(int j = 1 ; j <= i ;j++){printf("%d*%d=%2d ",j,i,i*j);}printf("\n");}return 0;
}
練習二:包含數字9的數
包含數字9的數_牛客題霸_牛客網
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int c = 0;for(int i = 1 ; i<= 2019 ; i++){//判斷i是否包含9//把i的每一位都拆出來int n = i;while(n){if(n % 10 == 9){c++;break;}n /= 10;} }cout << c << endl;return 0;
}
注意 : 在多層嵌套的循環中也可以使用 break , 但是要注意 , 一個break 只能跳出自己所在的循環 , 無法一次性跳出所有的循環 。?
練習三:斐波那契數列
B2064 斐波那契數列 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int n;cin >> n;int a = 0;while(n--)//n次詢問{cin >> a;int x = 1;int y = 1;int z = 1;while(a > 2){z = x + y ;x = y;y = z;a--; } cout << z << endl;} return 0;
}
練習四:求出e的值
B2079 求出 e 的值 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int n;cin >> n;double sum = 1;for(int i = 1;i<=n;i++){//算出i的階乘long long r = 1;for(int j=1;j<=i;j++){r *= j;}sum += 1.0 / r; }printf("%.10lf\n",sum);return 0;
}
優化 : 我們發現會有重復類乘的情況 ,比如求3! = 1*2*3 , 在算4! 的時候 又把 1*2*3 算了一遍 , 會有一點的時間消耗。
----> 計算階乘的時候 , 是有連續性的 , 我們可以借助這個特點 , 對代碼進行優化
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int n;cin >> n;double sum = 1;long long r = 1;for(int i = 1;i<=n;i++){r *= i;sum += 1.0 / r; }printf("%.10lf\n",sum);return 0;
}
練習五:三角形
信息學奧賽一本通(C++版)在線評測系統
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int n = 0;cin >> n;//輸出n行 for(int i = 1 ; i<= n;i++){//打印1行for(int j = 1 ; j <= i ; j++){cout<< "*"; } cout << endl;}return 0;
}
對于嵌套循環 , 一定要明白 , 每一個循環所對應的目標是什么 。?
練習六:畫矩形
B2083 畫矩形 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;int a,b;
char c;
int f;
int main()
{cin >> a >> b >> c >> f;if(f == 0){for(int i = 1;i<=a;i++){//打印1行for(int j = 1;j<=b;j++){if(i == 1 || i == a || j== 1 || j== b)cout << c;elsecout << " "; } cout << endl;} }else{//直接打印 a行b列的實心圖形for(int i = 1;i<=a;i++){//打印1行for(int j = 1;j<=b;j++){cout << c; } cout << endl;}}return 0;
}
我們還可以對以上代碼進行優化 :?
1 . 無論什么情況 , 第1行、第1列、第a行、第b列 都會打印c符
2 . 不同的是 , f為0時 , 中間的空格打印空字符? ,這里我們就可以用 else if ... else 語句來控制
#include <iostream>
#include <cstdio>
using namespace std;int a,b;
char c;
int f;
int main()
{cin >> a >> b >> c >> f;for(int i = 1;i<=a;i++){//打印1行for(int j = 1;j<=b;j++){if(i == 1 || i == a || j== 1 || j== b)cout << c;else if(f == 0)cout << " ";elsecout << c; } cout << endl;}return 0;
}
練習七:第n小的質數
B2085 第 n 小的質數 - 洛谷
#include <iostream>
#include <cstdio>
using namespace std;int main()
{int n;cin >> n;int i = 2;int c = 0;while(1){//判斷i是否為素數int flag = 1;//假設i是素數for(int j = 2 ; j<= i-1;j++){if(i % j == 0){flag = 0; break; }}if(flag == 1)c++;if(c == n){break; }i++; }cout << i << endl;return 0;
}
"Time Limit Exceeded"(TLE,超時)是?個在編程競賽和在線評測平臺(如LeetCode、Codeforces、HackerRank等)中常見的錯誤信息。它意味著程序在執行過程中超過了給定的最大運行時間限制,而未能在規定時間內得出結果。
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;int main()
{int n = 0;cin >> n;int c = 0;int i = 2;while(1){int flag = 1;//判斷i是否是素數for(int j = 2;j <= sqrt(i) ;j++){if(i % j == 0){flag = 0;break; } } if(flag == 1)c++;if( c == n){break;}i++;} cout << i << endl;return 0;
}
練習八 : 水仙花數
信息學奧賽一本通(C++版)在線評測系統
水仙花數 : 自冪數 --> 每個位上的數字的n次冪之和等于它本身
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;int main()
{for(int i = 100 ; i<= 999 ; i++){//判斷i是否為水仙花數 int tmp = i;int r = 0;while(tmp){r += pow(tmp % 10,3); tmp /= 10;}if(r == i)cout << i << endl;}return 0;
}