C語言

2020-08-13 13:58:34

Linux基本命令

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-OZFY1w5J-1597297949257)(D:\Software\typora\Picture\image-20200729155404399.png)]

  1. man手冊:man+指令 q退出
  2. ls -al可以列出所有檔案,包括隱藏檔案/ls -al a.out可以知道a.out的許可權
  3. 執行a.out:./a.out
  4. 檔案描述符 drwxr-xr-x
  5. cd … 返回上級目錄
  6. cd(什麼也不加)返回家目錄
  7. cd - 返回剛纔的目錄
  8. TAB補全,按兩下會出現可能的選擇
  9. pwd :列印出的是絕對路徑,從家目錄一直到現在的
  10. cp 拷貝檔案:cp 檔案 …/(目錄/) 複製到上一層目錄;
  11. rm * 刪除該目錄下的所有檔案;rm -r 檔案(目錄)遞回刪除該目錄下的所有檔案;rm -rf 目錄 確保有這個目錄,不然預設後面參數爲空,會遞回刪除當前目錄下的所有檔案

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-lDdzCr9F-1597297949260)(D:\Software\typora\Picture\image-20200803154949702.png)]

  1. touch 檔名:建立的是空檔案
  2. cat 檔名:強制讀取檔案內容到終端
  3. vim下面 下麪有三種模式,插入i/o/a,普通,命令模式
  4. 普通模式下dd可以刪除一行,快速儲存並退出ZZ(shift+zz)
  5. g++:編譯c++檔案;gcc:編譯c檔案;./a.out執行檔案
  6. 檔案中GG可以快速定位到最後一行,gg可以快速定位到第一行
  7. 複製貼上:普通模式下遊標所在行,按1yy可以複製一行,再按p可以貼上到遊標所在的下一行
  8. 剪下:普通模式下遊標移到所在行的頭,CTRL+v,進入到可視塊的模式,再選中內容,按y可以實現剪下,再需要的位置按p,完成貼上
  9. 撤回:普通模式下u可以退操作
  10. 刪除個別字元:普通模式下,遊標移到需要的位置,按x,刪除一個字元

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-VlEBZaLN-1597297949261)(D:\Software\typora\Picture\image-20200803161202085.png)]

  1. find ./ -name 檔名(例如0.cpp):顯示在哪個目錄下
  2. find / -name 檔名:在根目錄下查詢
  3. 忘記檔名時可以進行匹配,例如oj*

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-EIE2axWJ-1597297949263)(D:\Software\typora\Picture\image-20200803161734085.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-qMSTYvlV-1597297949265)(D:\Software\typora\Picture\image-20200803161803680.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-iSXjuBWm-1597297949266)(D:\Software\typora\Picture\image-20200803161836316.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-yRL72oAJ-1597297949267)(D:\Software\typora\Picture\image-20200803161902113.png)]

C語言入門基礎

  1. 程式=演算法+數據結構
  2. 程式設計=演算法+數據結構+程式設計範式
  3. C語言是程序導向,C++支援程序導向、物件導向、OO、泛型
  4. 程式設計規範:百度+谷歌,阿裡+谷歌
  5. 操作系統的發展
  6. 推薦工具書《C語言核心技術》
  7. [外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-Pc7Lf3DI-1597297949267)(D:\Software\typora\Picture\image-20200726185032235.png)]

1. 輸入輸出函數

1.原型

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-J0v3bOGw-1597297949268)(D:\Software\typora\Picture\image-20200803164910263.png)]

原型中:

  1. int表示printf的返回值是一個整型
  2. printf爲函數名
  3. 括號裡爲參數列表:格式控制字串,可變參數列表
  4. 返回值:例如printf(「hello world\n」); 的返回值是12,空格和\n各算一個

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-OvC6YtPn-1597297949269)(D:\Software\typora\Picture\image-20200805165419239.png)]

和printf類似

  1. scanf的返回值範圍是從0開始,-1是第一個非法返回值

  2. EOF:End Of File的縮寫,通常在文字的最後存在此字元表示資料結束,其值通常爲-1,常用做法

    while(scanf("%d",&n) != EOF)
    

2.隨堂練習

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-3OsW87BO-1597297949270)(D:\Software\typora\Picture\image-20200805170516083.png)]

#include<stdio.h>

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        printf(" has %d digits!\n", printf("%d", n));
    }
    return 0;
}

例:

輸入:123

輸出:123 has 3 digits!

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-UudC7C2x-1597297949270)(D:\Software\typora\Picture\image-20200805170915275.png)]

#include<stdio.h>

int main() {
    char a[1000] = {0};
    while (scanf("%[^\n]s", a) != EOF) {
        getchar();
        printf(" has %d chars!\n", printf("%s", a));
    }
    return 0;
}

例:

輸入:hello world

輸出:hello world has 11 chars!

  1. 其中scanf中「[]」是正則表達式字元匹配集,例如括號裏面是a~z,那麼只會讀入範圍裏面的字元,遇到不是的就會停止,^是取反,也就是說除了\n以外的都可以讀入;

  2. ./a.out > out叫做輸出重定向,執行的輸出結果到out這個檔案

  3. [外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-sAHwp4VX-1597297949271)(D:\Software\typora\Picture\image-20200805203416140.png)]

    按此程式執行,會輸出一大串

    [外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-jINDXbFk-1597297949272)(D:\Software\typora\Picture\image-20200805203555101.png)]

    只有第一次讀入了,後面是因爲第一次讀入完成後指針指向了\n,第二次的時候判定爲scanf返回值爲0,並不是-1,所以還會不斷的列印,造成死回圈

  • getchar(),可以強行吞掉一個字元,例如\n,那麼就不會進入死回圈。

3.printf家族函數程式碼演示

1.printf函數

#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n); //stdin標準輸入
    printf("%d\n",n); //stdout標準輸出
    char str[100] = "hello world"; //字串輸入
    printf("%s\n", str); // 字串輸出
    return 0;
}
#include <stdio.h>

int main() {
    int n;
    str ch[5];
    scanf("%d%s", &n, &ch[0]);
    printf("n = %d, ch = %s", n, ch[0]);
    return 0;
}

字串,可以以陣列的形式輸入;還有%s的用法

2.sprintf

s可以理解爲string,是將輸出列印到陣列當中去

  1. 例如,拼接192.168.1.10
#include <stdio.h>

int main() {
    char str[100] = {0};
    sprintf(str, "%d.%d.%d.%d", 192, 168, 1, 10);//輸出到str陣列
    printf("str = %s\n", str);//列印str陣列
    return 0;
}

輸出:str = 192.168.1.10

2.rwx(000~111),分別代表可讀,可寫,可執行,輸入一個數字判斷它的許可權,可讀的話加一個「()」,可寫的話加一個「[]」,可執行的話」{}「。

#include <stdio.h>
#define swap(a, b) {\
	__typeof(a) __temp = a;\
	a = b; b = __temp;\
}

int main() {
    char str[100] = {0}, buffer[100] = {0}, *p = str, *q = buffer;
    sprintf(str, "%d.%d.%d.%d", 192, 168, 1, 10);
    if (n & 1) {
        sprintf(q, "%s", p);
        swap(q, p);
    }
    if (n & 2) {
        sprintf(q, "[%s]", p);
        swap(q, p);
    }
    if (n & 4) {
        sprintf(q, "{%s}", p);
        swap(q, p);
    }
    printf("%s\n", p);
    return 0;
}
sprintf(str, "(%s)", str);//會出現錯誤,原因是str邊列印邊覆蓋

輸入:1;輸出:(192.168.1.10);

輸入:3;輸出:[(192.168.1.10)];

輸入:7;輸出:{[(192.168.1.10)]};

3.fprintf

f可以理解爲file,將輸出列印到檔案當中去

#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n);
    FILE *fout = fopen("./output", "w");//結果輸出到output檔案中,w代表以寫的方式
    fprintf(stdout, "%s\n", p);
    return 0;
}

這三個printf家族:三者的返回值,及格式是相同的

4.stdin/stdout/stderr

分別是標準輸入,標準輸出,標準錯誤輸出,輸出會展現在終端上,在輸出重定向的時候(>),stderr的值不會出現在檔案中,只會出現在終端上,而stdout可以。

2. 數學運算

1. 基本運算子

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-TRvQG5Hd-1597297949272)(D:\Software\typora\Picture\image-20200807133651461.png)]

逆運算是一種對應法則。假設A是一個非空集合,對A中的任意兩個元素a和b,根據某種法則使A中有唯一確定的元素c與它們對應,我們就說這個法則是A中的一種運算。反過來,如果已知元素c,以及元素a、b中的一個,按照某種法則,可以得到另一個元素,這樣的法則也定義了一種運算,這樣的運算叫做原來運算的逆運算。

如減法是加法的逆運算。a + b = c,那麼 c - a = b, c - b = a.

&與;|或;^互斥或(是本身的逆運算);~按位元取反;

例:~6 = -7;~(-6) = 5;正數儲存爲原碼,負數儲存爲二補數;

<<左移:補0,相當於*2;>>右移:高位補符號位(與原數正負一致),相當於/2;

2. 數學庫函數<math.h>

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-f4b812b7-1597297949273)(D:\Software\typora\Picture\image-20200807135905021.png)]

1. 指數函數pow

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-AH4x8548-1597297949274)(D:\Software\typora\Picture\image-20200807150751172.png)]

2. 開平方函數SQRT

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-MSkEiXfm-1597297949275)(D:\Software\typora\Picture\image-20200807151211644.png)]

3. 上取整函數CEIL

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-fISSnHFp-1597297949275)(D:\Software\typora\Picture\image-20200807151249492.png)]

也可叫」天花板「函數

4. 下取整函數FLOOR

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-10nieN4B-1597297949276)(D:\Software\typora\Picture\image-20200807151423371.png)]

也叫」地板「函數

5. 整數絕對值函數ABS

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-bWcojYro-1597297949276)(D:\Software\typora\Picture\image-20200807151823022.png)]

注意:標頭檔案爲<stdlib.h>

6. 實數絕對值函數FABS

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-1ElgzQFb-1597297949277)(D:\Software\typora\Picture\image-20200807152245400.png)]

7. LOG函數

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-T24CrM93-1597297949278)(D:\Software\typora\Picture\image-20200807152317558.png)]

8. LOG10函數

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-NLdPCUDo-1597297949279)(D:\Software\typora\Picture\image-20200807152345756.png)]

換底公式:
log28=loge8/loge2 log_{2} 8 = log_{e}8 / log_{e}2

9. ACOS函數

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-IhtH3VoS-1597297949280)(D:\Software\typora\Picture\image-20200807161734465.png)]

注意:x是弧度值,
=pi/180 弧度值 = 角度值 * \\pi / 180

3. 隨堂練習題

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-5brTyoFg-1597297949280)(D:\Software\typora\Picture\image-20200807162203166.png)]

#include <stdio.h>
#include <math.h>

int main() {
    double x;
    scanf("%f", &x);
    printf("%f\n", pow(x, 1.0/3.0));
    return 0;
}

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-kkBXKMTM-1597297949281)(D:\Software\typora\Picture\image-20200807162741786.png)]

#include <stdio.h>
#include <math.h>

#define PI acos(-1)
int main() {
    double x;
    scanf("%f", &x);
    printf("%lf", PI / 180.0 * x);
    return 0;
}

4. 極客學院(C語言參考手冊)

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-ue8lRyGE-1597297949282)(D:\Software\typora\Picture\image-20200807163017323.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-Ffs4ao88-1597297949283)(D:\Software\typora\Picture\image-20200807163109269.png)]

5. 數學運算程式碼演示

1. 加法

#include <stdio.h>

int main() {
    int a, b;
    while (scanf("%d%d", &a, &b) != EOF) {
        printf("%d\n", a + b);
    }
    return 0;
}

輸入:2 3;輸出:5

其中,

while (scanf("%d%d", &a, &b) != EOF)
可替換成
while (~scanf("%d%d", &a, &b))

2. C語言運算子優先順序

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-nqZ9jS72-1597297949283)(D:\Software\typora\Picture\image-20200807170629595.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-lu9XBIxC-1597297949284)(D:\Software\typora\Picture\image-20200807170648030.png)]

3. 交換兩個數(互斥或運算)

通過交換兩個地址完成交換

#include <stdio.h>

int main() {
    int a, b;
    while (~scanf("%d%d", &a, &b)) {
        int *p = &a;
        (*p)--;
        printf("a = %d, b = %d\n", a, b);
        a ^= b;
        b ^= a;
        a ^= b;
        printf("swap : a = %d, b = %d\n", a, b);
    }
    return 0;
}

4. 迴文數位

#include <stdio.h>

int rev(int n) {
	int sum = 0;
	while (n) {
		sum = sum * 10 + n % 10;
		n /= 10;
	}
	return sum;
}

int main() {
	int n;
	while (scanf("%d", &n) != EOF) {
		printf("%d\n", rev(n));
	}
	return 0;
}

輸入:123;輸出:321

6. bool型別

C語言支援bool型別,標頭檔案爲<stdbool.h>

#include <stdio.h>
#include <stdbool.h>
 
int main(void) {
    bool a=true, b=false;
    printf("%d\n", a&&b);
    printf("%d\n", a||b);
    printf("%d\n", !b);
}

輸出:0 1 1

7. <inttypes.h>標頭檔案

例如,int32_t,32表示32位元 = 4位元組,表示定義的整型變數佔空間大小爲4個位元組,能表示的最大整數爲2的31次方;

uint32_t,爲無符號整型,能表示大的最大整數爲2的32次方;

例如:INT32_MIN/INT32_MAX是一個宏,前者表示32位元表示的最小值,後者表示32位元的最大值

#include <stdio.h>
#include <inttypes.h>

int main() {
    int32_t a = 123;
    int64_t b = 256;
    int8_t c = 123;
    printf("a = %lu, b = %lu\n", sizeof(a), sizeof(b));//a=4,b=8
    printf("c = %" PRId8 "\n", c); //123
    printf("sizeof(c) = %" PRIu64 "\n", sizeof(c));//1
    printf("INT32_MIN = %d\n", INT32_MIN);//-2147483648
    printf("INT32_MAX = %d\n", INT32_MAX);//2147483647
    printf("INT16_MIN = %d\n", INT16_MIN);//-32768
    printf("INT16_MAX = %d\n", INT16_MAX);//32767
    printf("INT8_MIN = %d\n", INT8_MIN);//-128
    printf("INT8_MAX = %d\n", INT8_MAX);//127
    printf("PRId64 = %s\n", PRId64);//ld
    printf("PRId32 = %s\n", PRId32);//d
    printf("PRId16 = %s\n", PRId16);//d
    return 0;
}

PRIdx:也是一個宏,例PRId8,會自動匹配變數的型別

8. 逆運算

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-r0dCZdy7-1597297949285)(D:\Software\typora\Picture\image-20200809200111653.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-Oex2N5Yg-1597297949286)(D:\Software\typora\Picture\image-20200809200156843.png)]

3. 程式流程控制方法

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-1LPnFYWn-1597297949286)(D:\Software\typora\Picture\image-20200809132738849.png)]

1. C語言關係運算符

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-kHWWnPak-1597297949287)(D:\Software\typora\Picture\image-20200809115100150.png)]

返回值:true / false,即1 / 0;

!!(x) :歸一化,例如x = 5,結果爲1;x = 0,結果爲0;

三種結構:順序,分支或選擇,回圈;

2. 分支結構

1. if語句

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-DBJQKxOd-1597297949288)(D:\Software\typora\Picture\image-20200809123446334.png)]

還有,if (表達式) 程式碼塊;

隨堂練習

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-cvxSoeI7-1597297949293)(D:\Software\typora\Picture\image-20200809123840152.png)]

#include <stdio.h>

int main() {
	int n;
    scanf("%d", &n);
    if (!n) {
        printf("FOOLISH\n");
    } else if (n < 60) {
        printf("FAIL\n");
    } else if (n < 75) {
        printf("MEDIUM\n");
    } else if (n <= 100) {
        printf("GOOD\n");
    }
    return 0;
}

2. SWITCH語句

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-WAr9wlM1-1597297949294)(D:\Software\typora\Picture\image-20200809124420904.png)]

還有,default: 程式碼塊;break;

隨堂練習題-1

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-eGp2iRZ9-1597297949294)(D:\Software\typora\Picture\image-20200809124827946.png)]

#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n);
    switch(n) {
        case 1:
           printf("one\n");
           break;
        case 2:
           printf("two\n");
           break;
        case 3:
           printf("three\n");
           break;
        default :
           printf("ERROR\n");
    }
    return 0;
}
隨堂練習題-2

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-mYfd6XM1-1597297949296)(D:\Software\typora\Picture\image-20200809125209305.png)]

#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n);
    switch (n) {
        case 1:
           printf("one ");
        case 2:
           printf("two ");
        case 3:
        printf("three\n");
           break;
        default :
           printf("error\n");
           break;
    }
    return 0;
}

3. CPU的分支預測

迴文整數

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-jDjhJ2iz-1597297949296)(D:\Software\typora\Picture\image-20200809125809235.png)]

bool isPalindrome(int x) {
    if (__builtin_expect(!!(x < 0), 0)) return false;//首先排除掉x<0
    int y = 0, z = x;
    while (x) {
        y = y * 10 + x % 10;
        x /= 10;
    }
    return z == y;
}

__builtin_expect是一個宏,判斷x < 0 這種情況是經常成立還是不成立的,後面第二個0,是代表不經常成立,這就是分支預測;

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-vmPsM1EA-1597297949297)(D:\Software\typora\Picture\image-20200809131221932.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-rIkSLSDc-1597297949297)(D:\Software\typora\Picture\image-20200809130335828.png)]

分析程式執行方式(CPU):

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-KkLBLbbV-1597297949298)(D:\Software\typora\Picture\image-20200809130418594.png)]

執行速度:外存 < 記憶體 < 快取 < CPU;序列計算 < 並行計算;

__builtin_xxx宏

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-EQrSNeaJ-1597297949299)(D:\Software\typora\Picture\image-20200809131729729.png)]

可以幫助CPU做分支預測;

3. 回圈結構

1. WHILE 語句

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-v36lGD1Z-1597297949299)(D:\Software\typora\Picture\image-20200809132103330.png)]

隨堂練習題
image-20200809132229048
#include <stdio.h>

int main() {
    int n = 1;
    while (n < 101) {
        printf("%d\n", n);
        n ++;
    }
    return 0;
}
#include <stdio.h>

int main() {
    int n = 1;
    do {
        printf("%d\n", n);
        n ++;
    } while (n <= 100);
    return 0;
}

2. FOR 語句

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-6CA0mr4m-1597297949300)(D:\Software\typora\Picture\image-20200809132600291.png)]

也可以,初始化部分爲空;

隨堂練習
image-20200809132622841
#include <stdio.h>

int main() {
    int n;
    for (n = 1; n < 101; n++) {
        printf("%d\n", n);
    }
    return 0;
}

4. 程式流程控制程式碼演示

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    int a = 0, b = 0;
    if ((a++) && (b++)) {
        printf("true\n");
    } else {
        printf("false\n");
    }
    //輸出:false,a++是先用再加,&&運算子是前面不符合就不判斷後面了,直接下一步
    printf("test1 : a = %d, b = %d\n", a, b);
    //輸出:a = 1, b = 0
    if ((a++) || (b++)) {
        printf("true\n");
    } else {
        printf("false\n");
    }
    //輸出:true
    printf("test2 : a = %d, b = %d\n", a, b);
    //輸出:a= 2, b = 0
    int n, cnt = 0;
    scanf("%d", &n);
    srand(time(0));//隨機種子,標頭檔案<stdlib.h>,種子爲時間
    //time(0)是返回當前的系統時間
    //判斷奇偶
    if (n & 1) {
        printf("%d is a odd!\n", n);
    } else {
        printf("%d is a even!\n", n);
    }
    //0~100亂數
    for (int i = 0; i < n; i++) {
        int val = rand() % 100;
        i && printf(" ");//如果不是第一個數就可以有空格
         //也可以 i && printf(" "); 或者 i = 0 || printf(" ");
        printf("%d", val);
        cnt += (val & 1);//判斷奇數有幾個
    }
    printf("\n");
    printf("odd nums : %d\n", cnt);//輸出奇數有幾個
    //判斷數位的位數
    int x, digits = 0;
    scanf("%d", &x);
    do {
        digits++;
        x /= 10;
    } while (x); //可以包括0值
    printf("digits : %d\n", digits);
    return 0;
}

4. 函數

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-55h2oO0I-1597297949300)(D:\Software\typora\Picture\image-20200809205124489.png)]

有函數的,可讀性更高,更容易偵錯

1. 函數說明

功能:判斷素數; 整體程式碼塊是函數的定義

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-oRBPP95m-1597297949301)(D:\Software\typora\Picture\image-20200809205222562.png)]

返回值爲空時,可以用void;

1. 隨堂練習題

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-cTKdyius-1597297949302)(D:\Software\typora\Picture\image-20200809210202077.png)]

2. K&R風格的函數定義

比較古老,現在一般不這麼用

image-20200809210353081

參數變數的型別放在了」()「外面;

返回值是給操作系統看的;命令:echo $,如果結果爲0,表示上一條命令執行成功;

2. 遞回程式

image-20200809211638707

遞推是一種演算法;遞回是自己呼叫自己;

可以用數學歸納法,理解遞回;

1. 隨堂練習題

image-20200809212117334
#include <stdio.h>

int fac(int n) {
    if (n == 0) return 1; //邊界條件
    return n * fac(n - 1); //遞回過程
}

int main() {
    int n;
    while (~scanf("%d", &n)) {
        printf("fac(%d) = %d\n", n, fac(n));
    }
    return 0;
}

3. 函數指針

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-knwd8AAR-1597297949303)(D:\Software\typora\Picture\image-20200809213006681.png)]

把函數當作一個變數,傳進去;傳的是函數的地址;第一個int是函數的型別,第二個是函數的參數型別;最後的x是類似於分段函數的參數變數;

以歐拉計劃045題爲例;

4. 歐幾裡得演算法(輾轉相除法)

程式 = 演算法 + 數據結構

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-4dWO8yBc-1597297949304)(D:\Software\typora\Picture\image-20200806141028654.png)]

  1. 功能

求兩個數的最大公約數

  1. 理論分析

首先先上結論,求最大公約數,我們可以通過遞回gcd(a,b)=gcd(b,a%b),gcd(a,0)=a計算,複雜度是log(n);

很明顯,這個偉大的結論gcd(a,b)=gcd(b,a%b),就是著名的歐幾裡得公式。

那麼怎麼證,其實還挺簡單的。我們把證明分爲兩步驟:

1、證明gcd(a,b)是b,a%b的一個公約數

2、證明這個公約數是最大的。

1、我們設gcd(a,b)=d,再令a=k1d,b=k2d.

 我們再設,a=k*b+c(也就是a除以b商k餘c),那麼c就是餘數,也就是a%b.

 講上面那個式子移項,得到c=a-k*b,然後再把a=k1*d,b=k2*d,這兩個式子裡的a、b帶入式子,得到:

 c=k1*d-k*k2*d,在提取公因數d,得到c=(k1-k*k2)*d.這樣就說明,c,也就是a%b有d這個約數,因爲開始我們設b也有d這個約數,所以gcd(a,b)是b,a%b的一個公約數。

2、現在知道了它是一個公約數,那麼怎麼證它是最大的?(其實感性分析,a%b都變小了,公約數不可能更大呀!)

但是術學是一門嚴謹的學科,我們要嚴謹證明。我們知道,c(a%b)=(k1-kk2)d,b=k2d,我們只需要證明k1-kk2、k2互質就好了。

  這裏可以用到反證法:我們假設k1-k*k2=q*t,k2=p*t,並且t>1(也就是那兩個不互質)。

   我們將前面那個式子移項,得到k1=q*t+k*k2,再把這個k1代到最開始的a=k1*d,得到a=(q*t+k*k2)*d,再利用乘法分配律,得到:
   a=q*t*d+k*k2*d,我們這時發現,k2*d不就是最開始的b嗎?,將其帶入,得到:a=q*t*d+b*d.

這時,我們再把k2=pt代入開始的b=k2d,得到b=ptd,再把這個式子代到a=qtd+bd.得到了:a=qtd+pt*d.提取公因數:a=(q+p)td

現在,再和b=ptd比較,發現他們的最大公因數變成了t*d和開始矛盾,所以假設不成立,反證成功!

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-6ixnWTDl-1597297949304)(D:\Software\typora\Picture\20190207101619404.jpg)]

image-20200810094536225

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-d49MOzoN-1597297949305)(D:\Software\typora\Picture\image-20200810094554497.png)]

  1. 程式
#include <stdio.h>

int gcd(int a, int b) {
    return (b ? gcd(b, a % b) : a);//三目運算子b不爲0,執行gcd(b, a % b),否則執行a
}

int main() {
    int a, b;
    while (~scanf("%d%d", &a, &b)) {
        printf("%d\n", gcd(a, b));
    }
    return 0;
}

5. 擴充套件歐幾裡得演算法

  1. 功能

求解a * x + b * y = 1 方程的一組整數解;是求解a * x + b * y = gcd(a, b);

  1. 分析

先來看看一個重要的基本定理

裴蜀定理(貝祖定理)
對於整數a,b,他們關於x,y的線性不定方程ax+by=d,設gcd(a,b)=g,則可證明g|d,換句話說,就是g是a,b的最小線性組合。

證明:

設ax+by=d,g=gcd(a,b),設ax+by的最小值爲s,

∵ g|a,g|b

∴ g|d,g|s

設q=[as].則r=amods=a−q∗s=a−q∗(ax+by)=a(1−qx)+b(−qy)。

可見r也是x,y的線性組合,又r是s的餘數,r∈[0,s−1],又s是最小線性組合,∴r=0。

推出s|a,同理有s|b,則s|g,又已經有g|s,所以g=s。可知g是ax+by的最小線性組合。

推論:

a和b互質的充要條件是存在x,y使ax+by=1,因爲由上面的證明結論知道d(這裏是1)一定是gcd(a,b)的倍數。

其實還可以推廣到一堆數互質(這些數的gcd爲1)的情況。

拓展歐幾裡得
我們知道,一般的 歐幾裡得演算法是來求兩個數的最大公因數的,但是拓展歐幾裡得可以走得更遠,也就是說,它不僅僅求一個gcd,而是可以求出一些額外的東西。前面的定理說了a,b線性組合最小是gcd(a,b),我們就可以求出ax+by=gcd(a,b)對應的x,y出來。

怎麼求呢?我們已經知道當歐幾裡得演算法遞回到終點時,gcd(a,b)中的b已經是零,也就是說,這個時候a∗1+b∗0=a,x=1,y=0,我們就可以在這時反推上去求解最終的x,y

現在是遞回返回過程的某一步,我們已經求得了b和a%b的gcd,還有此時的x1,y1,就是說b∗x1+a%b∗y1=gcd,要怎麼求a,b的x,y呢?

我們知道a%b=a−[ab]∗b,gcd=b∗x1+(a−[ab]∗b)∗y1=b∗x1+a∗y1−[ab]∗y1∗b=a∗y1+(x1−[ab]∗y1)∗b=a∗x+b∗y

可以看出x=y1,y=x1−[ab]∗b.遞回返回時即可更新掉x,y的值返回即可。

  1. 程式
#include <stdio.h>

int ex_gcd(int a, int b, int *x, int *y) {
    if (!b) {
        *x = 1, *y = 0;
        return a;
    }
    int xx, yy, ret = ex_gcd(b, a % b, &xx, &yy);
    *x = yy;
    *y = xx - a / b * yy;
    return ret;
}

int main() {
    int a, b, x, y;
    while (~scanf("%d%d", &a, &b)) {
        printf("gcd(%d, %d) = %d\n", a, b, ex_gcd(a, b, &x, &y));
        printf("%d * %d + %d * %d = %d\n", a, x, b, y, a * x + b * y);
    }
    return 0;
}

輸入:3 5;輸出:gcd(3, 5) = 1, 3 * 2 + 5 * -1 = 1;

輸入:2 4;輸出:gcd(2 ,4) = 2, 2 * 1 + 4 * 0 = 2;

6. 變參函數

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-ynI369C2-1597297949305)(D:\Software\typora\Picture\image-20200806164202851.png)]

實現找到最大值:

#include <stdio.h>
#include <stdarg.h>

int max_int(int n, ...) {
    int ans = 0;
    va_list arg;//將變參列表存到arg
    va_start(arg, n);//定位到第一個參數位置
    while (n--) {
        int tmp = va_arg(arg, int);//arg中取int型別的變數
        if (tmp > ans) ans = tmp;
    }
    va_end(arg);//結束
    return ans;
}

int main() {
    printf("%d\n", max_int(3, 1, 5, 3));
    printf("%d\n", max_int(2, 1, 5));
    printf("%d\n", max_int(6, 1, 5, 3, 18, 2, 9));
    printf("%d\n", max_int(4, 1, 5, 3, 9, 18));//只會讀取前四個
    return 0;
}

歐拉(Euler)計劃

01 Multiples of 3 and 5(3的倍數和5的倍數)

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-mIB0ypud-1597297949306)(D:\Software\typora\Picture\image-20200807111237828.png)]

方法一:利用回圈,挨個判斷

#include <stdio.h>

int is_val(int n) {
    return n % 3 == 0 || n % 5 == 0;
}

int main() {
    int sum = 0;
    for (int i = 1; i < 1000; i++) {
        if (is_val(i)) sum += i;
    }
    printf("%d\n", sum);
    return 0;
}

這麼寫,時間複雜度爲O(n)

方法二:

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-lOTqzhJQ-1597297949306)(D:\Software\typora\Picture\image-20200807130102510.png)]

能被3或5整除的,可以用等差數列求和公式,相加,再減去公差爲15的等差數列求和,即爲答案,時間複雜度爲O(1)

#include <stdio.h>

int main() {
    int sum3 = (3 + 999) * 333 / 2;
    int sum5 = (5 + 995) * 199 / 2;
    int sum15 = (15 + 999 / 15 * 15) * (999 / 15) / 2;
    printf("%d\n", sum3 + sum5 - sum15);
    return 0;
}

Answer:233168

02 Even Fibonacci numbers(偶斐波那契數)

  1. 題目描述

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-apdCyABJ-1597297949307)(D:\Software\typora\Picture\image-20200809165117627.png)]

  1. 分析

Fib(n)=Fib(n1)+Fib(n2) Fib(n) = Fib(n-1)+Fib(n-2)

Fib(n1)=Fib(n2)+Fib(n3)......1 Fib(n-1) = Fib(n-2)+Fib(n-3)......1

Fib(n2)>=Fib(n3)......2 Fib(n-2) >= Fib(n-3)......2

Fib(n2)>=Fib(n1)Fib(n2) Fib(n-2) >= Fib(n-1)-Fib(n-2)

Fib(n2)>=0.5Fib(n1)......3 Fib(n-2) >= 0.5Fib(n-1)......3

Fib(n)Fib(n1)>=0.5Fib(n1) Fib(n)-Fib(n-1) >=0.5Fib(n-1)

Fib(n)>=1.5Fib(n1) Fib(n) >= 1.5Fib(n-1)

Fib(n)>=1.5n Fib(n) >= 1.5^{n}

1.5n=4,000,000 1.5^{n}=4,000,000

n=log1.5(4000000)=log2(4000000)log2(1.5)44 n= log_{1.5} (4000000)=\frac{log_{2} (4000000)}{log_{2} (1.5)} \approx 44

  1. 程式

方法一:遍歷所有Fib(n),再找出偶數求和;

#include <stdio.h>
#define max_n 44
#define N 4000000

int fib[max_n + 5] = {1, 2, 0};//多加5位,防止不夠用

int main() {
    int sum = 0;
    for (int i = 2; i <= max_n; i++) {
        fib[i] = fib[i - 1] + fib[i - 2];
    }
    for (int i = 0; i <= max_n; i++) {
        if (fib[i] <= N && !(fib[i] & 1)) sum += fib[i];
    }
    printf("%d\n", sum);
    return 0;
}

方法二:

a,,b往前走

image-20200809165235906
#include <stdio.h>

#define max_n 4000000

int main() {
    int a = 0, b = 1, sum = 0;
    while (a + b <=  max_n) {
        b = a + b;
        a = b - a;
        if (b & 1) continue;
        sum += b;
    }
    printf("%d\n", sum);
    return 0;
}

方法三:卷動陣列

#include <stdio.h>
#define max_n 4000000
int fib[2] = {0, 1};

int main() {
    int sum = 0, n = 1;
    while (fib[n % 2] + fib[(n - 1) % 2] <= max_n) {
        n++;
        fib[n % 2] = fib[(n - 1) % 2] + fib[(n - 2) % 2];
        if (fib[n % 2] & 1) continue;
        sum += fib[n % 2];
    }
    printf("%d\n", sum);
    return 0;
}

Answer:4613732

03 Largest prime factor(最大質因數)

  1. 題目描述
image-20200809174350817
  1. 題目分析
image-20200809174500590 image-20200809174541602
  1. 程式設計

    #include <stdio.h>
    #define max_n 600851475143LL
    
    int main() {
        int ans = 0, i = 2;
        long long n = max_n;
        while (i * i <= n) {
            if (n % i == 0) ans = i;
            while (n % i == 0) n /= i;
            i++;
        }//ans 爲什麼一定是素因子;素數篩的演算法
        if (n != 1) ans = n;//爲什麼一定要判斷;怕n本身是一個素數
        printf("%d\n", ans);
        return 0;
    }
    

04 Largest palindrome product(最大迴文乘積)

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-ic4roMUI-1597297949307)(D:\Software\typora\Picture\image-20200809113138034.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-zEBMZ9Ln-1597297949308)(D:\Software\typora\Picture\image-20200809113202357.png)]

#include <stdio.h>
//base代表進位制,base = 10 就爲十進制
int is_val(int n, int base) {
    int sum = 0, tmp = n;
    while (tmp) {
        sum = sum * base + tmp % base;
        tmp /= base;
    }
    return sum == n;
}//實現任何一個十進制數位,在base進位制下是不是迴文數位

int main() {
    int ans = 0;
    for (int a = 100; a < 1000; a++) {
        for (int b = a; b < 1000; b++) {
            int t = a * b;
            if (t > ans && is_val(t, 10)) ans = t;
        }
    }
    printf("%d\n", ans);
    return 0;
}

Answer:906609

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-Mi83ZbBO-1597297949309)(D:\Software\typora\Picture\image-20200809113250501.png)]

05 Smallest multiple(最小倍數)

  1. 題目描述
image-20200810094307920
  1. 分析
image-20200810094338937 image-20200810094422177

公式:a * b / gcd(a, b);

  1. 程式
#include <stdio.h>
#define max_n 20

int gcd(int a, int b) {
    return (b ? gcd(b, a % b) : a);
}

int main() {
    int ans = 1;
    for (int i = 1; i <= max_n; i++) {
        ans *= i / gcd(ans, i);
    }
    printf("%d\n", ans);
    return 0;
}

Answer: 232792560

06 Sum square difference(平方的和與和的平方之差)

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-XYuuQaXi-1597297949309)(D:\Software\typora\Picture\image-20200807131111204.png)]

方法一:

#include <stdio.h>

int main() {
    int sum1 = 0, sum2 = 0;
    for (int i = 1; i <= 100; i++) {
        sum1 += i * i;
        sum2 += i;
    }
    printf("%d\n", sum2 * sum2 - sum1);
    return 0;
}

這樣時間複雜度是O(n)

方法二:sum2可以用前n項求和公式,sum1可以用前n項平方和的公式

#include <stdio.h>
#define n 100

int main() {
    int sum2 = 5050; //前100項求和結果
    int sum1 = (2 * n * n * n + 3 * n * n + n) / 6;//平方和求和公式
    printf("%d\n", sum2 * sum2 - sum1);
    return 0;
}

Answer:25164150

08 Largest product in a series(連續數位最大乘積)

  1. 題目描述

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-Ue5NiwSl-1597297949310)(D:\Software\typora\Picture\image-20200809181645494.png)]

  1. 題目分析

滑動視窗法

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-IhVXwoIi-1597297949310)(D:\Software\typora\Picture\image-20200809182054576.png)]

  1. 程式
#include <stdio.h>
#include <string.h>
#define max_n 1000

char num[max_n + 5];

int main() {
    int len = 0;
    while (~scanf("%s", num + len)) len = strlen(num);//回圈讀入
    long long ans = 0, p = 1, zero = 0;
    for (int i = 0; num[i]; i++) {
        num[i] -= '0';
        if (num[i]) p *= num[i];
        else zero += 1;
        if (i < 13) continue;
        if (num[i - 13]) p /= num[i - 13];
        else zero -= 1;
        if (zero == 0 && p > ans) ans = p;
    }
    printf("%lld\n", ans);
    return 0;
}

先將這1000個數存到input檔案中:./a.out < input ;

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-AHMFfiOV-1597297949311)(D:\Software\typora\Picture\image-20200809200540952.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-igcBh1bo-1597297949311)(D:\Software\typora\Picture\image-20200809200558155.png)]

Answer:23514624000

15 Lattice paths(網格路徑)

  1. 題目描述

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-OwAW86JW-1597297949312)(D:\Software\typora\Picture\image-20200809201742538.png)]

  1. 分析

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-QBzsEQD6-1597297949312)(D:\Software\typora\Picture\image-20200809201841309.png)]

image-20200809201902254 image-20200809201941890
  1. 程式
#include <stdio.h>

int main() {
    long long m = 40, n = 20, ans = 1;
    while (m != 20 || n) {
        if (m != 20) ans *= m--;
        if (n && ans % n == 0) ans /= n--;
    }//乘一項,除一項
    printf("%lld\n", ans);
    return 0;
}

Answer:137846528820

17 Number letter counts(表達數位的英文字母計數)

  1. 題目描述

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-GEa5uTIW-1597297949313)(D:\Software\typora\Picture\image-20200810095404667.png)]

  1. 分析
image-20200810095451317 image-20200810095625408
  1. 程式
#include <stdio.h>
#define max_n 1000
//1~19數位的字母個數
static int num1[20] = {
    0, 3, 3, 5, 4, 4, 3, 5, 5, 4, 3,
    6, 6, 8, 8, 7, 7, 9, 8, 8
};
//整十的字母個數
static int num2[10] = {
    0, 0, 6, 6, 5, 5, 5, 7, 6, 6
};

int get_letters(int n) {
    if (n < 20) return num1[n];//20以內的情況
    if (n < 100) return num2[n / 10] + num1[n % 10];//220~100的情況
    if (n < 1000) {
        if (n % 100 == 0) return num1[n / 100] + 7;
        else return num1[n / 100] + 10 + get_letters(n % 100);
    }//100~1000的情況
    return 11;//1000的情況
}

int main() {
    int sum = 0;
    for (int i = 1; i <= max_n; i++) {
        sum += get_letters(i);//用get_letters函數獲取i這個數位所需要的字母個數
    }
    printf("%d\n", sum);
    return 0;
}

Answer:21124

28 Number spiral diagonals(螺旋數陣對角線)

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-8fOiRcsR-1597297949313)(D:\Software\typora\Picture\image-20200809100730932.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-TgOdov60-1597297949314)(D:\Software\typora\Picture\image-20200809103107799.png)]

  1. 找規律

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-V7Erd5Iz-1597297949314)(D:\Software\typora\Picture\image-20200809101413999.png)]

L1的邊長 = 3,右上角9 = L1邊長的平方;L2邊長 = 5,25 = L2邊長的平方;所以可確定,

右上角的數位規律 =
Ln2 L_{n} ^{2}
左上角的數位規律 =
Ln2Ln1 L_{n} ^{2} - (L_{n} -1)
左下角的數位規律 =
Ln22Ln1 L_{n} ^{2} - 2(L_{n} -1)
右下角的數位規律 =
Ln23Ln1 L_{n} ^{2} - 3(L_{n} -1)

  1. 求每一圈的和
    4Ln26Ln+6 4L_{n} ^{2} - 6L_{n} + 6

  2. 程式設計

    #include <stdio.h>
    
    int main() {
        int sum = 1;
        for (int l = 3; l <= 1001; l += 2) {
            sum += 4 * l * l - 6 * l + 6;
        }
        printf("%d\n", sum);
        return 0;
    }
    

    Answer:669171001

30 Digit fifth powers(各位數位的五次冪)

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-8S8UVf8N-1597297949315)(D:\Software\typora\Picture\image-20200809103146428.png)]

image-20200809112047822 image-20200809112111486

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-IdMpEosc-1597297949315)(D:\Software\typora\Picture\image-20200809112215715.png)]

#include <stdio.h>
#include <math.h>

const int N = pow(9, 5) * 6;

int val(int n) {
    int sum = 0, tmp = n;
    while (tmp) {
        sum += pow(tmp % 10, 5);
        tmp /= 10;
    }
    return sum == n;
}

int main() {
    int sum = 0;
    for (int i = 2; i <= N; i++) {
        if (!val(i)) continue;
        sum += i;
    }
    printf("%d\n", sum);
    return 0;
}

Answer:443839

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-71F0r0vo-1597297949316)(D:\Software\typora\Picture\image-20200809112621240.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-mvZZMOU3-1597297949317)(D:\Software\typora\Picture\image-20200809112636736.png)]

32 Pandigital products(全數位的乘積)

  1. 題目描述

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-IRUY4Wue-1597297949317)(D:\Software\typora\Picture\image-20200810101756995.png)]

  1. 分析

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-7NxouQrI-1597297949318)(D:\Software\typora\Picture\image-20200810101823776.png)]

image-20200810101838589 image-20200810101856633
  1. 程式

    #include <stdio.h>
    #include <math.h>
    //判斷數的位數
    int digit(int n) {
        return floor(log10(n)) + 1;
    }
    //判斷數位是否有重複
    int add_to_num(int *num, int n) {
        while (n) {
            if (num[n % 10]) return 0;
            num[n % 10] += 1;
            n /= 10;
        }
        return 1;
    }
    //判斷a,b,c是否有重複數位
    int is_val(int a, int b, int c) {
        if (digit(a) + digit(b) + digit(c) - 9) return 0;//確保包含1~9所有數位
        int num[10] = {0};
        num[0] = 1;
        int flag = 1;
        flag = flag && add_to_num(num, a);
        flag = flag && add_to_num(num, b);
        flag = flag && add_to_num(num, c);
        return flag;
    }
    
    int keep[10000] = {0};//標記陣列
    
    int main() {
        int sum = 0;
        for (int a = 1; a < 100; a++) {
            for (int b = a + 1; b < 10000; b++) {
                if (!is_val(a, b, a * b)) continue;
                if (keep[a * b]) continue;
                sum += a * b;
                keep[a * b] = 1;//將每一個a * b結果結束後置爲1,防止重複
                printf("%d * %d = %d\n", a, b, a * b);
            }
        }
        printf("%d\n", sum);
        return 0;
    }
    

    Answer: 45228

45 Triangular, pentagonal, and hexagonal(三角形數、五邊形數和六角形數)

  1. 題目描述
image-20200809213941602
  1. 程式
#include <stdio.h>
#include <inttypes.h>
//遞回過程
int64_t Triangele(int64_t n) {
    return n * (n + 1) / 2;
}

int64_t Pentagonal(int64_t n) {
    return n * (3 * n - 1) / 2;
}

int64_t Hexagonal(int64_t n) {
    return n * (2 * n - 1);
}
//二分法查詢
int64_t binary_search(int64_t (*func)(int64_t), int64_t n, int64_t x) {
    int64_t head = 1, tail = n, mid;
    while (head <= tail) {
        mid = (head + tail) >> 1;
        if (func(mid) == x) return 1;
        if (func(mid) < x) head = mid + 1;
        else tail = mid - 1;
    }
    return 0;
}
//主函數
int main() {
    int64_t n = 143;
    while (1) {
        n++;
        int64_t tmp = Hexagonal(n);
        if (!binary_search(Pentagonal, 2 * n, tmp)) continue;
        break;
    }
    printf("%" PRId64 "\n", Hexagonal(n));
    return 0;
}

Answer:1533776805

add_to_num(num, c);
return flag;
}

int keep[10000] = {0};//標記陣列

int main() {
int sum = 0;
for (int a = 1; a < 100; a++) {
for (int b = a + 1; b < 10000; b++) {
if (!is_val(a, b, a * b)) continue;
if (keep[a * b]) continue;
sum += a * b;
keep[a * b] = 1;//將每一個a * b結果結束後置爲1,防止重複
printf("%d * %d = %d\n", a, b, a * b);
}
}
printf("%d\n", sum);
return 0;
}


Answer: 45228

## 45  Triangular, pentagonal, and hexagonal(三角形數、五邊形數和六角形數)

1. 題目描述

<img src="D:\Software\typora\Picture\image-20200809213941602.png" alt="image-20200809213941602" style="zoom:67%;" />

2. 程式

```c
#include <stdio.h>
#include <inttypes.h>
//遞回過程
int64_t Triangele(int64_t n) {
 return n * (n + 1) / 2;
}

int64_t Pentagonal(int64_t n) {
 return n * (3 * n - 1) / 2;
}

int64_t Hexagonal(int64_t n) {
 return n * (2 * n - 1);
}
//二分法查詢
int64_t binary_search(int64_t (*func)(int64_t), int64_t n, int64_t x) {
 int64_t head = 1, tail = n, mid;
 while (head <= tail) {
     mid = (head + tail) >> 1;
     if (func(mid) == x) return 1;
     if (func(mid) < x) head = mid + 1;
     else tail = mid - 1;
 }
 return 0;
}
//主函數
int main() {
 int64_t n = 143;
 while (1) {
     n++;
     int64_t tmp = Hexagonal(n);
     if (!binary_search(Pentagonal, 2 * n, tmp)) continue;
     break;
 }
 printf("%" PRId64 "\n", Hexagonal(n));
 return 0;
}

Answer:1533776805