演算法競賽入門 陣列與字串

2021-10-11 06:21:07 字數 4432 閱讀 8295

例題3-1

tex中的引號走這

思路是用string讀取完後for迴圈結合計數器解題,但是getline()會被樣例的換行符卡死,書上的程式顯然寫得更簡潔更好(涉及到換行符的讀取還是用char)

更好的方法是邊讀取邊處理,這裡涉及兩個函式和eof

fgetc(),可以從檔案裡讀取字元,也可從標準輸入流裡fgetc(stdin),返回值是int,但我用得更多的是第二種

getchar(),從標準輸入流裡讀取字元,接收空格換行符等,返回int型別變數

eof不是換行符,而是表示檔案流末尾

ac**:

#include

using

namespace std;

intmain()

else

}return0;

}

總結:

三元表示式的運用縮短了**長度,比if更簡潔

取反符號比計數器取餘更好更簡潔

注意的是上面不能用%c,否則單引號與字元的單引號重複(但似乎可以利用轉義字元,但%s明顯更簡潔)

編譯器會自動為常量字串新增』\0』

例題3-2

wertyu走這

這裡的思路是利用map容器,書上是利用常量字元陣列,將鍵盤上的字元東歐按順序儲存在陣列中,輸出時進行+1即可

ac**:

#include

using

namespace std;

char c=

"`1234567890-=qwertyuiop\\asdfghjkl;'zxcvbnm,./"

;int

main()

else

}}

總結:

char陣列未賦值的地方預設是』'字元

常量陣列的運用

注意\涉及到轉義字元,如果想用字元表示』'要2個斜槓

例題3-3 回文詞

走這

思路是string接收反轉比較,映象串用map容器,但書上的**簡單得多多多多多,講道理四個判斷要用四個if語句,書上**利用線性關係一次解決

#include

using

namespace std;

const

char

* rev =

"a 3 hil jm o 2tuvwxy51se z 8 "

;const

char

* msg=

;char

revs

(char c)

intmain()

printf

("%s -- is %s\n\n"

,s,msg[p+m*2]

);//m、p的取值可以構成二進位制

}//多行輸出必換行

}

總結:

m、p變數作為標記變數記錄字串的性質,而字串陣列下標0~3,正好可以用兩個變數的取值表示,這樣結合就不用if語句判斷

這裡同樣是字串陣列的運用

這裡的二維字元陣列的宣告可以不用宣告每個字串的長度

例題3-4 猜數字遊戲的提示走這

思路就是…樣例都沒看懂,不明白一一對應和位置不同的是如何計數的,看答案**貌似是相同數字出現多次算不同種數,書上的**直接將位置不同的數問題轉化為相同數字在a,b出現的次數,取最小值就是相同次數,這思想十分妙,我是沒想到

ac**:

#include

using

namespace std;

#define maxn 1010

intmain()

if(!b[0])

break

;//正常猜測裡不會有0,(srds我不能理解)

/*a可以逐個統計,數字在兩序列裡出現的次數可以通過桶計數,取最小值*/

for(

int j=

1;j<

10;j++

) b+

=min

(c1,c2);}

printf

(" (%d,%d)\n"

,a,b-a);}

}}

總結:

相同元素在兩序列的出現次數轉化為桶計數取最小值

注意輸出格式,不要漏掉":"

例題3-5 生成元走這

這裡主要的知識點是預處理,可以在一定程度上防止tle

ac**:

#include

using

namespace std;

const

int maxn =

100010

;int a[maxn]

;int

main()

//i是y的生成元

if(a[y]==0

||a[y]

>i)

}int n;

scanf

("%d"

,&n)

;while

(n--

)}

例題3-6

circular sequence

思路就是…沒有思路,基礎沒打好以至於看到迴圈沒反應,看了書上的**才知道運用%符號

運用到環狀的題目大都用到%

ac**:

#include

using

namespace std;

intmain()

else

if(s[

(ans+j)

%s.size()

]==s[

(i+j)

%s.size()

])else}}

int i =0;

while

(isize()

)printf

("\n");

}}

總結:

利用%判斷輸出,這樣就不用substr

這裡注意每個情況都要判斷,相等是要繼續判斷的

習題3-4

週期串走這

問題分析:

思路是利用雙指標乙個個比較,然後錯了不停修…直到發現錯得離譜修不了為止

這裡仔細看題可以有更好的解法:因為字串一定是由迴圈的子串構成,所以可以列舉週期,並且巧妙利用週期和取餘的關係,就不用再開乙個變數

ac**:

#include

using

namespace std;

intmain()

}if(!ok)}}

if(n)

}}

總結:

凡是涉及週期的問題可以考慮利用取餘

一定要注意輸出格式

習題3-8 repeating decimals走這

問題分析:

思路就是…還是沒有思路,太懶了做程式設計題不願動筆

正解思路是模擬小數的除法,當餘數相同時說明出現了迴圈小數,以此為標記即可

**不管怎麼修都是錯,所以照搬了別人的**,以後待補

習題3-12 floating-point numbers走這

問題分析:

數學題,在紙上動筆即可解,但是不理解小數的儲存,以至於看了別人的題解才做出來

數字很大,如果不想高精度可以求對數,這樣更方便

浮點數的比較不要用==

ac**:

#include

using

namespace std;

doublef(

int m)

intmain()

}if(flag)

break;}

}}

總結:

double可以保持15位小數的精度

scanf讀取字串大概是用不了一起題目利用固定格式的技巧,因為會將固定格式當作字串的一部分

sscanf預設空格間隔,將字元陣列轉化為其他型別變數

演算法競賽入門陣列 字串

陣列陣列 1 陣列最好定義在main函式外面。只有放在外面,陣列才可以開的更大,在主函式中,陣列稍大就會異常退出。2 陣列a複製k個元素到陣列b,memcpy b,a,sizeof int k 全部複製memcpy b,a,sizeof a 3 memset a,0,sizeof a 作用 把陣列a...

演算法競賽入門經典三 陣列和字串

include using namespace std intmain 輸出 100384,其中56轉換成了16進製制 34.568,其中四捨五入保留了3位小數 2.用c 的流,相當於重新讀入,實現數字轉string類。流不會讀入空格。include using namespace std intm...

演算法競賽入門經典(一) 陣列和字串

目錄 陣列和字串 逆序輸出 陣列的輸入與輸出 開燈問題 蛇形填數 斜線填數 一字填數 豎式問題 輸入一些數,統計個數 將數值儲存到動態陣列中 輸入一些數,輸出最大值,最小值 include define max 105 int a max int main 注意 如果要結束陣列的輸入並輸出陣列,需要...