PAT甲級考前整理(2019年3月備考)之二,持續更新中.....


PAT甲級考前整理之一網址:https://www.cnblogs.com/jlyg/p/7525244.html,主要總結了前面131題的類型以及易錯題及坑點。

PAT甲級考前整理三網址:https://www.cnblogs.com/jlyg/p/10364727.html主要是講132題開始的題目。

考前注意:

  1、寫函數(有返回值的函數)容易忘記返回值,可能本地運行沒問題,但是提交了就會有問題。

  2、不要把strlen()函數寫到for、while的循環中,有時候會超時,最好是 int len = strlen(str);提前求出來。

  3、用sort比較的時候,比較函數 int comp(const ST& st1,const ST& st2);如果在comp中調用ST的fun函數,fun函數必須加上const,例子 int fun()const{return 0;}

  4、二位數組初始化不要直接賦值,比如int a[10][10] ={0},是錯誤的,應該使用memset(a,0,sizeof(a));(一維數組也最好不要直接復制,通過循環復制最好)

  5、不要使用gets,PAT系統不支持。可以使用fprintf,使用fprintf注意最后一個字符是'\n',特別是比較的時候就不相等了。使用這一類函數時,注意需要把前一個輸入的'\n'使用getchar去掉。

string mygets()
{
    char str[300];
    fgets(str,sizeof(str),stdin);
    int len = strlen(str);
    if(str[len-1]=='\n') str[len-1] = '\0';    \\最后一行可能沒有換行符
    return str;
}
View Code

 

  6、使用freopen("1.txt","r",stdin);來減少測試的時間。因為PAT里有定義ONLINE_JUDGE,所以你需要背一下,寫錯就沒辦了。用以下代碼就無需在提交的時候修改就能提交(節約大量時間呀!!)

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;

int main()
{
       #ifndef ONLINE_JUDGE
            freopen("test.txt","r",stdin);
        #endif // ONLINE_JUDGE
    return 0;
}
View Code

 

  7、輸出時注意單復數,比如單數是a、is,復數是加s、are。

  8、不要還沒輸入完就用break跳出,不然會有問題,具體可以看我以下代碼和代碼中的注釋,例題PAT1122

View Code

  9、輸出id和編號的時候,如果你存儲是數字,請加上前面補足比如4位整型,%04d,用%d的時候就有問題了,比如0001輸出就是1。

  10、格式輸入了解一下,比如時間"10:20:50"你可以用scanf("%d:%d:%d",&h,&m,&s)。這樣可以省去一部分轉換的時間。

  11、數組開的過大可能會有問題

  12、若圖比較復雜,使用dfs會爆棧(段錯誤),此時可以選擇bfs。(PAT真題1091)

    13、rounded up是四舍五入,不是向上取整。

  14、二分法給的數據可能左端比右端大,可以做一下1012就知道了。

  15、對數字字符串操作時,要注意數字0端是高位,而不是低位,你可能需要倒轉字符串之類的。(PAT真題1024)

  16、字符串數字,轉換成數字需要去前導零,但是要考慮“0”的情況(PAT整體1038)

  17、排序或者二叉樹如果沒有說明不同,就說明存在有相同的值。

  STL總結:

    1.vector

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
void display(vector<int> vi)
{
    for(int i=0;i<vi.size();++i)
        printf("%d ",vi[i]);
    printf("\n");
}
int main()
{
    vector<int> vi;
    vi.push_back(1);
    vi.push_back(3);
    display(vi);
    //插入
    vi.insert(vi.begin()+1,2);
    display(vi);
    //刪除
    vi.erase(vi.begin()+2);
    display(vi);
    //清空
    vi.clear();
    return 0;
}
View Code

 

      2.queue與priority_queue

#include<iostream>
#include<queue>
#include<vector>
#include<cstdio>
using namespace std;

int main()
{
    //優先隊列會自動排序
    priority_queue<int,vector<int>,greater<int> >pq;
    pq.push(3);
    pq.push(2);
    pq.push(1);
    while(!pq.empty())
    {
        //queue的話是front函數
        int data = pq.top();
        pq.pop();
        printf("%d ",data);
    }
    printf("\n");
    return 0;
}
View Code

 

    3.map

#include<iostream>
#include<cstdio>
#include<map>
using namespace std;

int main()
{
    map<int,int> mii;
    mii.insert(pair<int,int>(1,1));
    mii[2] = 2;
    printf("刪除前:%d\n",mii[2]);
    //刪除key=2的值
    mii.erase(2);
    printf("刪除后:%d\n",mii[2]);
    return 0;
}
View Code

 

    4.string

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;

int main()
{
    char str[] = "hello world";
    string s(str);
    printf("%s\n",s.c_str());
    int index = s.find(' ');
    string s2 = s.substr(0,index);
    string s3 = s.substr(index+1,s.length()-index-1);
    printf("%s\n%s\n",s2.c_str(),s3.c_str());
    //字符串追加
    string newstr = "";
    newstr += s2;
    newstr += "-";
    newstr += s3;
    printf("%s\n",newstr.c_str());
    //字符串比較
    s2 = "aabc",s3="aacc";
    printf("%d\n",s2.compare(s3));

}
View Code

 

    5.set

#include<iostream>
#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;

void display(char* str,set<int> si)
{
    printf("%s: ",str);
    set<int>::iterator it = si.begin();
    for(;it != si.end();it++)
        printf("%d ",*it);
    printf("\n");
}
int main()
{
    set<int> s1;
    set<int> s2;
    s1.insert(1);
    s1.insert(2);
    s1.insert(3);
    s2.insert(3);
    s2.insert(4);
    s2.insert(5);
    s2.insert(6);
    display("s1",s1);
    display("s2",s2);
    //erase的參數是key
    s2.erase(6);
    display("s2",s2);
    set<int> s3,s4;
    //交集
    set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s3,s3.begin()));
    //並集
    set_union(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s4,s4.begin()));
    display("交集",s3);
    display("並集",s4);
    return 0;
}
View Code

     

    6、map、set、vector、queue、stack的遍歷

#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<stack>
using namespace std;

int main()
{
    int n = 10;
    vector<int> vi;
    for(int i=0;i<n;++i)
        vi.push_back(i);
    printf("vector的遍歷:");
    for(int i=0;i<n;++i)
        printf("%d ",vi[i]);
    puts("");
    printf("set的遍歷:");
    set<int> si;
    for(int i=0;i<n;++i)
        si.insert(i);
    for(set<int>::iterator it=si.begin();it!=si.end();it++)
        printf("%d ",*it);
    printf("\nmap的遍歷:");
    //map和set的遍歷只能用iterator的方式
    map<int,int> mii;
    for(int i=0;i<n;++i)
        mii[i] = i;
    for(map<int,int>::iterator it=mii.begin();it!=mii.end();it++)
        printf("[%d %d] ",it->first,it->second);
    printf("\nqueue的遍歷:");
    //queue和statck遍歷只能通過讀取和pop的方式
    queue<int> qi;  //先進先出
    for(int i=0;i<n;++i)
        qi.push(i);
    while(!qi.empty())
    {
        printf("%d ",qi.front());
        qi.pop();
    }
    printf("\nstack的遍歷:");
    stack<int> st;
    for(int i=0;i<n;++i)
        st.push(i);
    while(!st.empty())
    {
        printf("%d ",st.top());
        st.pop();
    }
    puts("");
    return 0;
}
View Code

 

   一些樹的算法:

  如何判斷一顆樹是完全二叉樹,例題可以看PAT1123,可以用一個隊列,每次加入一個節點的左右節點,並且pop出該節點,如果該節點為空,則跳出循環,如果該樹是完全二叉樹,則隊列中應該都是null,如果存在非空,就說明不是完全二叉樹

bool isCBT(Node* root)
{
    queue<Node*> q; q.push(root); Node* node; while(node=q.front()) { q.push(node->left); q.push(node->right); q.pop(); } while(!q.empty()) { if(q.front()) return false; else q.pop(); } return true; }

   二叉樹的層級遍歷(非遞歸)

bool bFirst = true;
void level_travel(Node* root) { queue<Node*> q; q.push(root); Node* node; while(!q.empty()&&(node=q.front())) { if(bFirst) bFirst = false; else printf(" "); printf("%d",node->val); if(node->left) q.push(node->left); if(node->right) q.push(node->right); q.pop(); } }

 

  判斷圖是否遍歷所有點以下是錯誤的例子(PAT1126)

void dfs(int curI,int istep)
{
    if(istep==n) { flag = true; return; } for(int nextI=1;nextI<=n;++nextI) { if(Map[curI][nextI]&&!bVis[nextI]) { bVis[nextI] = true; dfs(nextI,istep+1); } } }

如 圖

      1

              3      2    4

從2節點遍歷,1,3,4,它的step為2

應該用以下判斷:判斷sum是否等於頂點個數。

int sum=0;
void dfs(int curI,int istep) { ++sum; for(int nextI=1;nextI<=n;++nextI) { if(Map[curI][nextI]&&!bVis[nextI]) { bVis[nextI] = true; dfs(nextI,istep+1); } } }

   如何優化BST搜索的效率,還在思考(當給出一個BST時,當測試數據極端時,二叉樹等同於線性結構,此時如何優化搜索效率)。

  二叉樹的遍歷可以看https://www.cnblogs.com/jlyg/p/10354622.html,主要整理了幾種二叉樹遍歷的類型,如已知中序和前序求后序?已知前序和后序求中序?已知中序完全二叉樹求廣度?已知先序的搜索二叉樹求后序?

  有時間可以看一下AVL樹的模板:https://www.cnblogs.com/jlyg/p/7521434.html

  紅黑樹只要了解性質就好了https://www.cnblogs.com/jlyg/p/10361506.html,實現比較繁瑣肯定不考。

  其他:

  Dijkstra模板:https://www.cnblogs.com/jlyg/p/7404082.html

  Pim模板(從沒考過):https://www.cnblogs.com/jlyg/p/10371948.html

  並查集的例題:https://www.cnblogs.com/jlyg/p/7356992.html

  DFS和BFS肯定是要必會的,這里就不多講了。DFS注意剪紙就好了,如果map超時就用vector保存路徑。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM