題解 2021PAT春季甲級

2022-06-29 16:27:17 字數 4706 閱讀 9492

【7-1 arithmetic progression of primes】

篩法預處理區間內的素數

因為已知數列長度,如果知道數列第

一、二個數即可求得整個數列

暴力列舉前兩個數,看後續是否滿足兩個條件

在所有找出的符合的數列中按題目要求得到最後應該輸出的那個數列

特殊情況:

①(n=1 || n==2&&m==2 || n>2&&找不到符合數列)時輸出區間內最大的素數

②n==2&&m>2時輸出2和區間內最大的素數

1 #include2

using

namespace

std;34

int n,m,top,pri[100100],anstop,ans[10000][20];5

bool f[100100

],fail;67

intmain()815

}16for (int i=2; i<=100000; ++i) if (!f[i]) pri[++top]=i; //

收集素數以便列舉

17while (pri[top]>m) top--;

18 fail=0; //

fail=1表示特殊情況1

19if (n>2)20

27 num+=x;28}

29if (!flag) continue

;30 anstop++; ans[anstop][0]=x; ans[anstop][1]=pri[i]; //

符合的都裝進ans陣列中

31for (int k=2; k<=n; ++k) ans[anstop][k]=ans[anstop][k-1]+x;32}

33if (!anstop) fail=1;34

else

3544 printf("

%d",ans[maxi][1

]);45

for (int i=2; i<=n; ++i) printf("%d"

,ans[maxi][i]);46}

47}48int maxpri; //

區間內最大素數

49for (int i=m; i>=2; --i) if (!f[i])

50if (n==2)51

55if (n==1) fail=1;56

if (fail) printf("%d"

,maxpri);

57return0;

58 }

【7-2 lab access scheduling】

將時間封裝到結構體內

並按開始時間為第一關鍵字,結束時間為第二關鍵字排序

排序完之後用動態規劃求解

f[i]表示前i個數中以第i個結尾的最多通過的申請

那麼更新f[i]時只需掃一遍前面的f[1]~f[i-1]看是否能接在他們後面即可

1 #include2 #include3 #include4 #include5

using

namespace

std;67

const

int n=2010;8

intn;

9struct node1; //

node1封裝時間

10struct node2a[n]; //

a[i]表示每個申請,將每個申請的兩個時間封裝

11char s[100

];12

intf[n];

1314 inline bool cmp1(node1 x,node1 y) //

x<=y時返回1

1521 inline bool c***(node1 x,node1 y) //

當且僅當x=y時返回1

2228 inline bool cmp2(node2 x,node2 y) //

sort函式的引數

2934

intmain()

3548 sort(a+1,a+n+1,cmp2); //

排序 49 f[1]=1;50

for (int i=2; i<=n; ++i)

5155 printf("%d"

,f[n]);

56return0;

57 }

【7-3 structure of max-heap】

按順序建大根堆,讀入詢問並輸出

由堆的性質可知:

1、根節點下標為1

2、左兒子下標+1=右兒子下標

3、左右兒子下標/2=父親下標

4、左兒子下標為奇數,右兒子下標為偶數

設xpos為x在堆中的位置(下標),ypos同理

各種詢問的判斷方式如下:

①xpos==1

②xpos是偶數 && ypos是奇數 && xpos+1==ypos(預設xpos

1 #include2 #include3 #include4

using

namespace

std;56

const

int n=1010;7

intn,m,a[n];

8int h[n<<1

],top;

9char

s[n];

1011

int x,y,xpos,ypos=-1;12

13 inline int find(int x) //

返回值x在堆中的位置,找不到則返回-1

1418 inline void pushup(int

x)19

24else

break;25

}26}27

intmain()

2835

for (int k=1; k<=m; ++k)

3645 scanf("

%s",&s); scanf("

%s",&s);

46if (s[0]=='

r'&&s[1]=='

o')//

前兩個字元為ro表示是第一種詢問

4751

if (s[0]=='

p')//

第乙個字元為p表示是第三種詢問

5257

if (s[0]=='

l')//

第乙個字元為l表示是第四種詢問

58 //

剩下的即為第五種詢問

63 scanf("

%s",&s); scanf("

%s",&s); scanf("

%d",&y); ypos=find(y);

64if (xpos/2==ypos&&xpos%2==1) printf("

1"); else printf("0"

);65}66

return0;

67 }

【7-4 recycling of shared bicycles】

鄰接矩陣存圖

以每個點為起點用spfa演算法跑單源最短路

按題意以0為起點每次去乙個距離最短且未標記的點,並記錄下來

第一行便輸出記錄下來的順序

若並不是所有點都互相聯通則最後還有點未標記,

這些未標記的點即為以0為起點走不到的點

最後注意:

1、達不到的距離我們用inf(乙個極大數)表示,因為不知道聯通兩點的最短距離的上限會是多少,

所以我就無腦開long long來使inf可以取到很大的數

2、spfa我沒有用迴圈佇列,所以我就把佇列的陣列q開的很大

1 #include2

#define ll long long

3using

namespace

std;45

const ll n=250,inf=2e11;

6ll n,m,a[n][n];

7ll ans[n],top,s;

8 ll dis[n][n],h,t,q[10000100

];9 ll ansdis=0;10

bool

f[n];

1112

intmain()

1322

for (int l=0; l<=n; ++l)

2335}36

}37 top=1; f[0]=1; s=0; bool flag=1;38

for (int l=1; l<=n; ++l)

3943

if (minn==inf)

44 ans[++top]=minpos; ansdis+=minn; f[minpos]=1; s=minpos;45}

46 printf("

0"); //

第乙個點必是0

47for (int i=2; i<=top; ++i) printf("

%lld

",ans[i]); //

這樣輸出不會有行末空格

48 printf("\n"

);49

if (flag) printf("

%lld

",ansdis);

50else

5159}60

return0;

61 }

2021春季PAT甲級

從零基礎開始備考,備考了45天,最後拿了94分,有些遺憾 最後一道題,最後乙個測試點沒有過,今天偶然在看晴神筆記的時候,知道了是弗洛伊德演算法實現錯誤,請看第四題詳解。建立素數表,從最大的間隔開始列舉,這樣不會超時。includeusing namespace std int n,maxp int ...

PAT甲級2020春季真題題解

簽到題,可以使用stoi將字串轉換為數字,然後試除法判斷是否為素數。include include using namespace std bool check const string s intmain 取子串 使用unordered set來做,比set效率高,如果不要求集合有序的話。incl...

PAT甲級2019春季真題題解

簽到題,素數不需要用篩法,直接o sqrt n 即可。熱身題,字串處理,使用集合判斷。稍難,圖論 並查集,還有要理解題意 個人認為pat最難的點 include include include define ac cin.tie 0 cin.sync with stdio 0 using names...