PAT甲級考前整理(2019年3月備考)之一


    轉載請注明出處:https://www.cnblogs.com/jlyg/p/7525244.html

      終於在考前,刷完PAT甲級131道題目,不容易!!!每天沉迷在刷題之中而不能超脫,也是一種境界。PAT甲級題目總的說卡題目的比較多,卡測試點的比較少,有些題目還會有題意混淆,這點就不吐槽了吧。靜下心來耍這130道題,其實磨練的是一種態度與手感,養成的是一種習慣。熱愛AC沒有錯!!(根據自己的刷題情況持續更新中,這次是第二遍刷了,發現換了新網站后,oj嚴格很多了,有些之前可以過的,現在已經不能過了)

  PAT甲級復習之二:主要寫一些考前注意,以及常見算法。網址通道https://www.cnblogs.com/jlyg/p/10364696.html

  PAT甲級復習之三:主要是131題后的題目,網址通道https://www.cnblogs.com/jlyg/p/10364727.html

  131道題目主要的考點:

    1、排序:快速排序,直接插入排序,希爾排序,分治排序,堆排序。

    2、圖論:拓撲排序(好像沒考過)、最短路徑、深度搜索、廣度搜索。

    3、樹:樹的遍歷、完全二叉樹、AVL,CBT,BST。

    4、其他:並查集,模擬,哈希(二次探測一次,簡單hash多次)、背包(一次),lcs(一次),最大子和(一次),set(一次),1057(分塊搜索)

  主要算法:快排、直接插入排序、希爾排序、分治排序、堆排序、拓撲排序、dijkstra,floyd,dfs,bfs,AVL,並查集,樹遍歷算法。

  

  題目分類:

  1003(dfs or dijkstra)、1004(dfs)、1007(最長子和)、1010(二分查找)、1013(並查集)、1020(二叉樹,前后序求廣度)、1021(並查集)、1024(大數加法)、1029(歸並排序)、1030(dikstra)、1043(前序判斷是否是二叉收縮樹)、1044(二分查找)、1045(lcs)、1053(dfs)、1063set)、1064(二叉搜索樹)、1066(AVL)、1068(背包問題)、1076(bfs)、1078(hash二次探測)、1079(bfs,dfs)、1086(中前序求后序)、1089(排序)、1094(bfs or 並查集),1098(排序)、1099(BST)、1101(快排)、1102(反轉二叉樹)、1103(dfs剪枝)、1107(並查集)、1110(完全二叉樹)、1111(dijkstra)、1114(並查集)、1115(BST)、1118(並查集)、1119(前后序求中序)、1123(AVL)、1127(bfs)、1130(dfs)




    dijkstra: 100310301111
    dfs:     10031004105310791103(dfs剪枝)、1130
    bfs:1076107910941127
    排序:1029(歸並排序)、108910981101(快排)
    並查集:101310211094110711141118
    二叉樹:1020(前后序求廣度)、1043(前序判斷是否是二叉搜索樹)、1064(二叉搜索樹)、1066(AVL)、1086(中前序求后序)、1099(BST)、1102(反轉二叉樹)、1110(完全二叉樹)、1115(BST)、1119(前后序求中序)、1123(AVL)
    二分查找:10101044
    其他:1007(最長子和)、1024(大數加法)、1045(lcs)、1063set)、1068(背包問題)、1078(hash二次探測)
View Code

   錯誤修改:1013不是並查集,應該是dfs,剛剛發現,抱歉。

       1010這題目會比較奇怪,屬於題意不清,第一可能會超出long long int,第二需要使用二分法不然超時,第三進制是無限制的可以是2到無限

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
long long int change(const char* strnum,long long int jinzhi)
{
    long long int len = strlen(strnum);
    long long int res = 0;
    for(long long int i=len-1,k=1;i>=0;--i,k*=jinzhi)
    {
        long long int a;
        if(strnum[i]>='0'&& strnum[i]<='9') a = strnum[i]-'0';
        else a = strnum[i]-'a'+10;
        res += k*a;
    }
    return res;
}

long long int Find_Radix(char* strnum,long long int dst,long long int left,long long int right)
{
    long long int mid = (left+right)/2;
    long long int midnum = change(strnum,mid);
    if(left==right)
    {
        if(dst != midnum) return -1;
        return left;
    }
    else if(left > right)
    {
        return -1;
    }
    if(midnum==dst)
    {
        return mid;
    }
    if(midnum<0||dst<midnum)
    {
        return Find_Radix(strnum,dst,left,mid-1);
    }
    else
    {
        return Find_Radix(strnum,dst,mid+1,right);
    }
}

int main()
{
    //freopen("test.txt","r",stdin);
    char s1[20],s2[20];
    int tag,jinzhi;
    scanf("%s%s%d%d",s1,s2,&tag,&jinzhi);
    if(tag==2)  {swap(s1,s2);}
    long long int a = change(s1,jinzhi);
    long long int left = 0;
    int len = strlen(s2);
    for(int i=0;i<len;++i)
    {
        long long int temp;
        if(s2[i]>='0'&&s2[i]<='9')
        {
            temp = s2[i]-'0';
        }
        else
        {
            temp = s2[i] - 'a'+10;
        }
        left = max(temp+1,left);
    }
    left = max((long long int)2,left);
    long long int right = max(a,left);
    long long int res = Find_Radix(s2,a,left,right);
    if(res==-1)
    {
        printf("Impossible\n");
    }
    else
    {
        printf("%lld\n",res);
    }
    return 0;
}
View Code

       1012題目排名是可以有並列的,比如有並列第1的情況。
       1014這道題的問題在於只要在17:00之前開始的就是正常的,結束時間是可以超過17:00后的,有點坑吧。

  1017模擬題,看代碼和注釋,很詳細

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
int gettick(int h,int m,int s)
{
    return h*60*60+m*60+s;
}
const int window_starttime = gettick(8,0,0);
const int window_endtime = gettick(17,0,0);
struct Customer
{
    int cometime;   //來到時間
    int protime;    //處理時間,秒
};
int getfreewindow(int* windows,int k)
{
    int mintime = windows[0],mink = 0;
    for(int i=1;i<k;++i)
    {
        if(mintime > windows[i])
        {
            mink = i;
            mintime = windows[i];
        }
    }
    //注釋1:該種情況就是,這個人是17點之前來的,但是前面有人結束后就已經是17點以后了,這種情況也不需要過濾,還是計算在內的。
    //if(mintime>window_endtime) return -1;
    return mink;
}
int cmp(const Customer& c1,const Customer& c2)
{
    return c1.cometime < c2.cometime;
}

int main()
{
    #ifdef ONLINE_JUDGE
    #else
        freopen("test.txt","r",stdin);
    #endif
    int n,k;
    scanf("%d%d",&n,&k);
    vector<Customer> vcus;
    for(int i=0;i<n;++i)
    {
        int h,m,s,p;
        scanf("%d:%d:%d%d",&h,&m,&s,&p);
        Customer cus;
        cus.cometime = gettick(h,m,s);
        cus.protime = min(60*p,60*60);
        if(cus.cometime <= window_endtime)      //過濾17點以后來的人
            vcus.push_back(cus);
    }
    n = vcus.size();
    sort(vcus.begin(),vcus.end(),cmp);
    int twaittime = 0/*總等待時間*/,cnt=0/*得到處理的人數*/,windowstime[k]/*該窗口空閑時間*/;
    for(int i=0;i<k;++i)
        windowstime[i] = window_starttime;
    for(int i=0;i<n;++i)
    {
        int iw = getfreewindow(windowstime,k);
        if(iw==-1) break;
        ++cnt;
        Customer &cus = vcus[i];
        if(cus.cometime<windowstime[iw])
        {
            twaittime+= (windowstime[iw]-cus.cometime);
            windowstime[iw] += cus.protime;
        }
        else
        {
            windowstime[iw] = cus.cometime + cus.protime;
        }
    }
    if(cnt==0) printf("0.0\n");
    else printf("%.1lf\n",1.0f*twaittime/cnt/60);
    return 0;
}
View Code

   1018題:dfs,求最小路徑,若相同求最小借出的bike數,再若相同,求最小還回的bike數。要注意路徑(cmax=10)PBM->(3)->(10),它的send為2,back為5,而不是send為0,back3(后面多出來的不能補到前面的,前面多出來的可以補到后面)

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
#define N (510)
const int INF = (1<<30);
int cmax,n,sp,m;
int cap[N];
int Len[N][N];
vector<int> Map[N];
bool bVis[N];
int minlen = INF;
int minsend = 0;
int minback= 0;
vector<int> minPath;
void dfs(int curI,int len,vector<int> path)
{
    if(curI==sp)
    {
        if(len <= minlen)
        {
            int curminsend = 0,curminback = 0;
            for(int i=1;i<path.size();++i)
            {
                int curcap = cap[path[i]];
                if(curcap<cmax/2)   //少了
                {
                    int adjust = cmax/2 - curcap;
                    if(adjust <= curminback)
                    {
                        curminback -= adjust;
                    }
                    else
                    {
                        adjust -= curminback;
                        curminback = 0;
                        curminsend += adjust;
                    }
                }
                else if(curcap>cmax/2)  //多了
                {
                    curminback += (curcap-cmax/2);
                }
            }
            if(len<minlen||(len==minlen&&curminsend<minsend)||
                (len==minlen&&curminsend==minsend&&curminback<minback))
            {
                minlen = len;
                minPath = path;
                minsend = curminsend;
                minback = curminback;
            }
        }
        return;
    }
    if(len >= minlen) return;
    for(int i=0;i<Map[curI].size();++i)
    {
        int nextI = Map[curI][i];
        if(!bVis[nextI])
        {
            bVis[nextI] = true;
            path.push_back(nextI);
            dfs(nextI,len+Len[curI][nextI],path);
            path.pop_back();
            bVis[nextI] = false;
        }
    }

}
int main()
{
    #ifdef ONLINE_JUDGE
    #else
        freopen("test.txt","r",stdin);
    #endif
    scanf("%d%d%d%d",&cmax,&n,&sp,&m);
    for(int i=0;i<=n;++i)
        for(int j=0;j<=n;++j)
            if(i==j) Len[i][j] = 0;
            else Len[i][j] = INF;
    for(int i=1;i<=n;++i)
        scanf("%d",&cap[i]);
    for(int i=0;i<m;++i)
    {
        int a,b,l;
        scanf("%d%d%d",&a,&b,&l);
        Len[a][b] = Len[b][a] = l;
        Map[a].push_back(b);
        Map[b].push_back(a);
    }
    bVis[0] = true;
    vector<int> path;
    path.push_back(0);
    dfs(0,1,path);
    printf("%d ",minsend);
    for(int i=0;i<minPath.size();++i)
    {
        if(i) printf("->");
        printf("%d",minPath[i]);
    }
    printf(" %d\n",minback);
    return 0;
}
View Code


       1022題,需要用到整行輸入字符串,而PAT的c++編譯器是無法調用gets的,可以用fgets(buf,sizeof(buf),stdin);//讀入的數據需要去掉\n。如果在fgets函數之前調用了scanf,就必須要使用getchar把換行好讀掉。

   當然也可以用 while(cin>>str)

        {
           char  c;
          c= getchar ();
           if (c== '\n' )      break ;
        }
  
#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
void mygets(string& str)
{
    char temp[100];
    fgets(temp,sizeof(temp),stdin);
    temp[strlen(temp)-1] = '\0';
    str = temp;
}

map<string,set<int> > mapbname;
map<string,set<int> > mapauthor;
map<string,set<int> > mapkey;
map<string,set<int> > mappublisher;
map<string,set<int> >    mapyear;
struct Book
{
    int id;
    string bname;
    string author;
    string key;
    string publisher;
    string year;
    set<string> setkey;
    void Read()
    {
        scanf("%d",&id);
        getchar();
        mygets(bname);
        mygets(author);
        mygets(key);
        mygets(publisher);
        mygets(year);
        DealKey();
        mapbname[bname].insert(id);
        mapauthor[author].insert(id);
        mappublisher[publisher].insert(id);
        mapyear[year].insert(id);
    }
    void DealKey()
    {
        int len = key.length();
        string words = "";
        for(int i=0;i<len;++i)
        {
            if(key[i]!=' ') words += key[i];
            if(i==len-1||key[i]==' ')
            {
                if(!words.empty())
                {
                    setkey.insert(words);
                    mapkey[words].insert(id);
                }
                words = "";
            }
        }
        /*set<string>::iterator it = setkey.begin();
        for(;it!=setkey.end();it++)
            printf("%s\n",it->c_str());
            */

    }
};
int main()
{
    #ifdef ONLINE_JUDGE
    #else
        freopen("test.txt","r",stdin);
    #endif
    int t;
    scanf("%d",&t);
    while(t--)
    {
        Book book;
        book.Read();
    }
    scanf("%d",&t);
    while(t--)
    {
        int opt;
        string str;
        scanf("%d: ",&opt);
        mygets(str);
        printf("%d: %s\n",opt,str.c_str());
        map<string,set<int> > *mss = NULL;
        if(opt==1) mss = &mapbname;
        else if(opt==2) mss = &mapauthor;
        else if(opt==3) mss = &mapkey;
        else if(opt==4) mss = &mappublisher;
        else if(opt==5) mss = &mapyear;
        if(mss->find(str)!=mss->end())
        {
            set<int> &si = (*mss)[str];
            set<int>::iterator it = si.begin();
            for(;it!=si.end();it++)
            {
                printf("%07d\n",*it);
            }
            if(si.size()==0) printf("Not Found\n");
        }
        else
        {
            printf("Not Found\n");
        }
    }
    return 0;
}
View Code

 

  1024題:輸入本身就是回文串時,直接輸出該回文串,並且輸出步數為0.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
#define N (100)
bool isPal(char* str)
{
    int l = strlen(str);
    for(int i=0;i<l/2;++i)
        if(str[i] != str[l-i-1]) return false;
    return true;
}
void Add(char* str)
{
    char temp[N];
    int iAdd = 0;
    int l = strlen(str);
    int tlen = 0;
    for(int i=0;i<l;++i)
    {
        int res = str[i]-'0'+str[l-i-1]-'0' +iAdd;
        temp[tlen++] = res%10 + '0';
        iAdd = res/10;
    }
    if(iAdd) temp[tlen++] = iAdd + '0';
    temp[tlen] = '\0';
    string strTemp = temp;
    reverse(strTemp.begin(),strTemp.end()); //反轉
    strcpy(str,strTemp.c_str());
}
int main()
{
    char strNum[N];
    int k;
    scanf("%s%d",strNum,&k);
    int step = 0;
    while(!isPal(strNum)&&step<k)
    {
        Add(strNum);
        ++step;
    }
    printf("%s\n",strNum);
    printf("%d\n",step);
    return 0;
}
View Code

      1026題:題目比較坑:

    1、處理時間有超過2個小時的,需要自己代碼判斷大於2個小時,變成兩個小時。

    2、21:00:00之后不處理,包括21點整。

    3、當有普通球台和VIP球台時,VIP客戶遵循選擇最小編號的VIP球台,而非編號最小的普通球台;普通客戶遵循選擇最小的球台

    4、四舍五入,不然最后一個case過不了。

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
#define N (10010)
int getTick(int h,int m,int s)
{
    return 60*60*h+60*m+s;
}
const int SartTime = getTick(8,0,0);
const int EndTime = getTick(21,0,0);
bool bTableVip[N];
int  tableperson[N];        //每張桌子處理的人數
int  tabfreetime[N];        //每張桌子空閑時間
int tables;     //桌子數
struct Custom
{
    int arrivingtime;       //到達時間
    int servingtime;        //開始服務時間
    int playingtime;           //玩耍時間
};
int getFreeTable(int& freeviptableid) //該函數返回一個編號最小,最早空閑時間的桌子編號,freeviptable表示vip中編號最小的,最早空閑時間的桌子編號
{
    int tablesid = -1,mintime = getTick(30,0,0),minviptime=getTick(30,0,0);
    freeviptableid = -1;
    for(int i=1;i<=tables;++i)
    {
        if(tabfreetime[i]<mintime)
        {
            mintime = tabfreetime[i];
            tablesid = i;
        }
        if(bTableVip[i]&&tabfreetime[i]<minviptime)
        {
            minviptime = tabfreetime[i];
            freeviptableid = i;
        }
    }
    return tablesid;
}
bool cmp(const Custom& c1,const Custom& c2)
{
    return c1.arrivingtime < c2.arrivingtime;
}
bool cmp2(const Custom& c1,const Custom& c2)
{
    return c1.servingtime < c2.servingtime;
}
void printtime(int tick)
{
    printf("%02d:%02d:%02d ",tick/3600,tick%3600/60,tick%60);
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("test.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int n;
    scanf("%d",&n);
    vector<Custom>cus,cusvip;
    for(int i=0;i<n;++i)
    {
        Custom c;
        int h,m,s,bVip;
        scanf("%d:%d:%d%d%d",&h,&m,&s,&c.playingtime,&bVip);
        c.arrivingtime = getTick(h,m,s);
        c.playingtime = min(2*60*60,c.playingtime*60);    //轉換成秒
        if(bVip) cusvip.push_back(c);
        else cus.push_back(c);
    }
    //加入末尾哨兵,這樣當下面運用是不需要考慮vector為空的時候
    Custom finalcus;
    finalcus.arrivingtime = getTick(30,0,0);
    cus.push_back(finalcus);
    cusvip.push_back(finalcus);
    sort(cus.begin(),cus.end(),cmp);
    sort(cusvip.begin(),cusvip.end(),cmp);
    int m;
    scanf("%d%d",&tables,&m);
    for(int i=0;i<m;++i)
    {
        int tableid;
        scanf("%d",&tableid);
        bTableVip[tableid] = 1;
    }
    for(int i=0;i<tables;++i) tabfreetime[i+1] = SartTime;
    vector<Custom> res;
    for(int i=0;i<n;++i)
    {
        int freeviptableid;
        int freetableid = getFreeTable(freeviptableid);
        Custom curcus;
        if(cusvip[0].arrivingtime<cus[0].arrivingtime||     /*當vip用戶早到時,vip用戶肯定先上桌*/
           bTableVip[freetableid]&&cusvip[0].arrivingtime<=tabfreetime[freetableid])  /*如果vip用戶晚到,但是這桌是vip專用桌,此時要看vip到達時間是否在桌有空之前到達*/
        {
            curcus = cusvip[0];
            cusvip.erase(cusvip.begin());
            if(freeviptableid!=-1&&curcus.arrivingtime>=tabfreetime[freeviptableid])    //vip用戶來的比最小vip桌空閑時間晚,這個時候前面即使有空閑普通桌,也要選擇vip桌。
                freetableid = freeviptableid;
        }
        else
        {
            curcus = cus[0];
            cus.erase(cus.begin());
        }
        if(tabfreetime[freetableid]>=EndTime||curcus.arrivingtime>=EndTime)
        {
            break;
        }
        curcus.servingtime = max(tabfreetime[freetableid],curcus.arrivingtime);
        tabfreetime[freetableid] = curcus.servingtime + curcus.playingtime;
        ++tableperson[freetableid];
        res.push_back(curcus);
    }
    sort(res.begin(),res.end(),cmp2);
    for(int i=0;i<res.size();++i)
    {
        printtime(res[i].arrivingtime);
        printtime(res[i].servingtime);
        int waittime = max(0,res[i].servingtime - res[i].arrivingtime);
        waittime = (int)(1.0*waittime/60+0.5);
        printf("%d\n",waittime);
    }
    for(int i=1;i<=tables;++i)
    {
        if(i-1) printf(" ");
        printf("%d",tableperson[i]);
    }
    printf("\n");
    return 0;
}
View Code

 

      1029題:坑點,內存超出限制,找到中位數之后,就無需再繼續往隊列中push。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<algorithm>
#include<iterator>
#include<queue>
using namespace std;
#define N (2*100000+1)
#define INF (1<<30)

queue<int> a;
queue<int> b;
int main()
{
    int n,m;
    scanf("%d",&n);
    for(int i=0;i<n;++i)
    {
        int temp;
        scanf("%d",&temp);
        a.push(temp);
    }
    a.push(INF);
    scanf("%d",&m);
    int iCnt = 0;
    int iMid = -1;
    for(int i=0;i<m;++i)
    {
        int temp;
        scanf("%d",&temp);
        if(iMid == -1)
        {
            b.push(temp);
            if(iCnt==(m+n+1)/2-1)
            {
                iMid = min(a.front(),b.front());
            }
            if(a.front()<b.front()) a.pop();
            else b.pop();
        }
        ++iCnt;
    }
    b.push(INF);
    for(;iCnt<=(m+n+1)/2-1;++iCnt)
    {
        iMid = min(a.front(),b.front());
        if(a.front()<b.front()) a.pop();
        else b.pop();
    }
    printf("%d\n",iMid);
    return 0;
}
View Code

   用數組的做法,類似分治排序的方法(可以看算法導論中對分治排序的講解,寫的特別好!!)

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

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("1.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int n1,n2;
    scanf("%d",&n1);
    int a1[n1+1];
    for(int i=0;i<n1;++i)
        scanf("%d",&a1[i]);
    scanf("%d",&n2);
    int res = 0,k=0,j=0;
    for(int i=0;i<n2;++i)
    {
        int num;
        scanf("%d",&num);
        while(a1[j]<num&&k<(n1+n2+1)/2)
        {
            res = a1[j++];
            k++;
        }
        if(a1[j]>=num&&k<(n1+n2+1)/2)
        {
            res = num;
            k++;
        }
    }
    //這一行容易忘記,因為k可能沒有到中位數。
    while(k++<(n1+n2+1)/2)
        res = a1[j++];
    printf("%d\n",res);
    return 0;
}
View Code

 

  1031題:坑點,當字符串長度是9的時候,試試,比如123456789,正確輸出是,計算 n2 = (N+2+2)/3,而不是n2=(N+2)/3;這種算出來n2可能會比n1,n3小

      

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>

using namespace std;
int main()
{
    char str[100];
    //while(true)
    {
        scanf("%s",str);
        int len = strlen(str);
        int n1,n2,n3 = (len+2+2)/3;
        n3 = max(3,n3);
        for(;n3<=len;++n3)
            if((len+2-n3)%2==0)
                break;
        int space = n3-2;
        n1 = n2 = (len - n3 + 2)/2;
        for(int i=0;i<n1-1;++i)
        {
            printf("%c",str[i]);
            for(int j=0;j<space;++j)
                printf(" ");
            printf("%c\n",str[len-i-1]);
        }
        printf("%c",str[n1-1]);
        for(int i=n1;i<n1+space;++i)
            printf("%c",str[i]);
        printf("%c\n",str[n1-1+n3-1]);
    }

    return 0;
}
View Code

        1032題:坑點,當搜索的兩個起點是一樣的時候測試點 。個人覺得應該還要考慮兩個起點是直接父子關系的情況(但是測試點中沒有。。。)

        

1 1 3
1 c 2
2 a 3
3 b -1
#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
using namespace std;
#define N (100000+10)
vector<int> vcPath[N];
bool bVis[N] = {0};
int iComPos = -1;
void dfs(int iCurI)
{     
    bVis[iCurI] = true;
    for(int i=0;i<vcPath[iCurI].size();++i)
    {
        int iNextI = vcPath[iCurI][i];
        if(false==bVis[iNextI])
            dfs(iNextI);
        else
        {
            iComPos = iNextI;
            return;
        }
    }
}
int main()
{
    int s1,s2,n;
    scanf("%d%d%d",&s1,&s2,&n);
    if(s1 == s2) iComPos = s1;
    for(int i=0;i<n;++i)
    {
        int a,b;
        char c[10];
        scanf("%d%s%d",&a,c,&b);
        if(s1 == a && s2 == b || s2==a&&s1==b)
        {
            iComPos = b;    
        }
        if(b != -1)
        {
            vcPath[a].push_back(b);
        }
    }    
    if(-1 == iComPos)
    {
        dfs(s1);
        dfs(s2);
    }
    if(-1==iComPos) printf("%d\n",-1);
    else printf("%05d\n",iComPos);
    return 0;
}
/*
1 2 2
1 c 2
2 a -1
*/
View Code

       1033題:坑點2:1)終點可能是起點,2)如果當前加油點可以直接開到終點,並且后面幾個點都比他大的話,就無需遍歷接來的點了(這題是真的很煩。。。。目測不是考試原題,僅僅是練習題)

  1)尋找必須要加油的站點加入到set中,搜索距離為dis的站點+滿油時行駛距離之內的所有站點,找最近的比dis單價便宜的站點,如果沒有,則找這段距離中價格最便宜的。

  2)根據set中的判斷這次的加油站價格是否比下一個加油站的價格小,如果是,則加滿油,否則加的油能夠支持到下一個加油站就行了。

  解法1:第二點需要特殊處理

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

int main()
{
    int iCmax,d,davg,n;
    scanf("%d%d%d%d",&iCmax,&d,&davg,&n);
    map<int,double> mis;
    for(int i=0;i<n;++i)
    {
        double p;
        int iDis;
        scanf("%lf%d",&p,&iDis);
        if(iDis >= d) continue;
        if(mis.find(iDis)==mis.end())
            mis[iDis] = p;
        else
            if(mis[iDis]>p) mis[iDis] = p;
    }
    if(mis.size()==0||mis.begin()->first!=0)    //一個測試點
    {
        printf("The maximum travel distance = 0.00\n");
    }
    else if(d==0)    //沒有測試點
    {
        printf("0.00\n");
    }
    else
    {
        double iMaxLen = iCmax*davg;
        map<int,double>::iterator it = mis.begin();
        set<int> si;
        while(it!=mis.end()&&it->first < d)
        {
            map<int,double>::iterator tit = it;
            si.insert(it->first);
            double fDis = it->first;
            double fPrice = it->second;
            double fMinPrice = -1;
            double fMinDis = -1;
            //如果當前加油點可以直接開到終點,並且后面幾個點都比他大的話,就無需遍歷接來的點了
            bool bBreak = true;
            if(fDis+iMaxLen>=d)
            {
                for(;tit!=mis.end();++tit)
                {
                    if(tit->second < fPrice)
                    {
                        bBreak = false;
                        break;
                    }
                }
                if(bBreak) break;
            }

            tit = it;
            while(++tit != mis.end())
            {
                if(tit->first - fDis <= iMaxLen && tit->first < d)
                {
                    if(fMinDis == -1 || fMinPrice > tit->second)
                    {
                        fMinDis = tit->first;
                        fMinPrice = tit->second;
                        if(fMinPrice < fPrice)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    break;
                }
            }
            tit = mis.find(fMinDis);
            if(tit != it)
            {
                it = tit;
            }
            else break;
        }
        set<int>::iterator sit = si.begin();
        double fTotal = 0;
        double fCurCap = 0;
        for(int i=0;sit != si.end();sit++,++i)
        {
            if(i == si.size()-1)
            {
                if(*sit+iMaxLen < d)
                {
                    printf("The maximum travel distance = %.2lf\n",*sit+iMaxLen);
                }
                else
                {
                    //printf("gas=%.2lf\n",1.0*(d-*sit)/davg-fCurCap);
                    fTotal += (1.0*(d-*sit)/davg-fCurCap)*mis[*sit];
                    printf("%.2lf\n",fTotal);
                }
            }
            else
            {
                set<int>::iterator nextsit = sit;
                ++nextsit;
                if(mis[*nextsit] > mis[*sit])
                {
                    //printf("gas=%.2f\n",iCmax-fCurCap);
                    fTotal += 1.0*(iCmax-fCurCap)*mis[*sit];
                    fCurCap = iCmax - 1.0*(*nextsit-*sit)/davg;
                }
                else
                {
                    //printf("gas=%.2f\n",(*nextsit-*sit)/davg-fCurCap);
                    fTotal += (1.0*(*nextsit-*sit)/davg-fCurCap)*mis[*sit];
                    fCurCap = 0;
                }
            }
            //printf("[%d %.2f]\n",*sit,fTotal);
        }
    }
    return 0;
}
View Code

  解法2:把終點看作一個加油站,油價為0,則無需再考慮第二點

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

int main()
{
    int iCmax,d,davg,n;
    scanf("%d%d%d%d",&iCmax,&d,&davg,&n);
    map<int,double> mis;
    for(int i=0;i<n;++i)
    {
        double p;
        int iDis;
        scanf("%lf%d",&p,&iDis);
        if(iDis >= d) continue;
        if(mis.find(iDis)==mis.end())
            mis[iDis] = p;
        else
            if(mis[iDis]>p) mis[iDis] = p;
    }
    mis[d] = 0;
    if(d&&mis.size()==1||mis.begin()->first!=0)    //一個測試點
    {
        printf("The maximum travel distance = 0.00\n");
    }
    else if(d==0)    //沒有測試點
    {
        printf("0.00\n");
    }
    else
    {
        double iMaxLen = iCmax*davg;
        map<int,double>::iterator it = mis.begin();
        set<int> si;
        while(it!=mis.end())
        {
            map<int,double>::iterator tit = it;
            si.insert(it->first);
            double fDis = it->first;
            double fPrice = it->second;
            double fMinPrice = -1;
            double fMinDis = -1;
            while(++tit != mis.end())
            {
                if(tit->first - fDis <= iMaxLen)
                {
                    if(fMinDis == -1 || fMinPrice > tit->second)
                    {
                        fMinDis = tit->first;
                        fMinPrice = tit->second;
                        if(fMinPrice < fPrice)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    break;
                }
            }
            tit = mis.find(fMinDis);
            if(tit != it)
            {
                it = tit;
            }
            else break;
        }
        set<int>::iterator sit = si.begin();
        double fTotal = 0;
        double fCurCap = 0;
        for(int i=0;sit != si.end();sit++,++i)
        {
            if(i == si.size()-1)
            {
                if(*sit+iMaxLen < d)
                {
                    printf("The maximum travel distance = %.2lf\n",*sit+iMaxLen);
                }
                else
                {
                    //printf("gas=%.2lf\n",1.0*(d-*sit)/davg-fCurCap);
                    fTotal += (1.0*(d-*sit)/davg-fCurCap)*mis[*sit];
                    printf("%.2lf\n",fTotal);
                }
            }
            else
            {
                set<int>::iterator nextsit = sit;
                ++nextsit;
                if(mis[*nextsit] > mis[*sit])
                {
                    //printf("gas=%.2f\n",iCmax-fCurCap);
                    fTotal += 1.0*(iCmax-fCurCap)*mis[*sit];
                    fCurCap = iCmax - 1.0*(*nextsit-*sit)/davg;
                }
                else
                {
                    //printf("gas=%.2f\n",(*nextsit-*sit)/davg-fCurCap);
                    fTotal += (1.0*(*nextsit-*sit)/davg-fCurCap)*mis[*sit];
                    fCurCap = 0;
                }
            }
            //printf("[%d %.2f]\n",*sit,fTotal);
        }
    }
    return 0;
}
View Code

 

  1034題:用dfs題來做,我把名字轉換成數字的時候剛開始弄錯了死活2個case沒過去((str[0]-'A')+(str[1]-'A')*26+(str[2]-'A')*26*26;)其實正確的是((str[2]-'A')+(str[1]-'A')*26+(str[0]-'A')*26*26;)不然用map或者set默認排序時會有問題。

  

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<string>
#include<iterator>
using namespace std;
#define N (26*26*26+10)
int n,k;
int val[N] = {0};
bool bVis[N] = {1};
vector<int> vcMap[N];
map<int,int> Res;
int GetNum(char* str)
{
    return (str[2]-'A')+(str[1]-'A')*26+(str[0]-'A')*26*26;
}
string GetStr(int num)
{
    char str[4] = {0};
    str[2] = num%26+'A';
    str[1] = num/26%26+'A';
    str[0] = num/26/26+'A'; 
    return str;
}
int iMaxCnt = 0,iMaxI = 0,iMaxMin = 0;
void dfs(int curI)
{
    bVis[curI] = true;
    ++iMaxCnt;
    iMaxMin += val[curI];
    if(val[iMaxI] < val[curI]) iMaxI = curI; 
    for(int i=0;i<vcMap[curI].size();++i)
    {
        int NextI = vcMap[curI][i];
        if(!bVis[NextI])
            dfs(NextI); 
    }
}
int main()
{
    scanf("%d%d",&n,&k);
    int iMaxN = 0;
    for(int i=0;i<n;++i)
    {
        char s1[4],s2[4];
        int m;
        scanf("%s%s%d",s1,s2,&m);
        int ia = GetNum(s1),ib=GetNum(s2);
        val[ia] += m;
        val[ib] += m;
        bVis[ia] = false;
        bVis[ib] = false;
        vcMap[ia].push_back(ib);
        vcMap[ib].push_back(ia);
        iMaxN = max(iMaxN,max(ia,ib));
    }
    for(int i=0;i<=iMaxN;++i)
    {
        if(!bVis[i])
        {
            iMaxCnt = 0,iMaxI = i,iMaxMin = 0;
            dfs(i);
            if(iMaxCnt > 2 && iMaxMin>2*k)
            {
                Res[iMaxI] = iMaxCnt;
            }
        }
    }
    printf("%d\n",Res.size());
    map<int,int>::iterator it = Res.begin();
    for(;it!=Res.end();it++)
        printf("%s %d\n",GetStr(it->first).c_str(),it->second);
    return 0;
}
View Code

       1035題:注意輸出是單數是 is 1 account ,雙數是 are N accounts;

     1038題:通過sort排序,比較方法是s1+s2,s2+s1判斷誰小就好了。輸出的時候考慮前面的0去掉,2 0 00 別輸出是00,但是后面的0不能去掉了(剛開始我就把后面的0也去掉了)比如3 00 01 001我的輸出是11(這是錯的)

  

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
int cmp(const string& s1,const string& s2)
{
    string temp1 = s1 + s2;
    string temp2 = s2 + s1;
    for(int i=0;i<temp1.length();++i)
    {
        if(temp1[i] != temp2[i])
            return temp1[i] - temp2[i] < 0;
    }
    return 1;
}
int main()
{
    //while(true)
    {
        vector<string> vs;
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;++i)
        {
            char str[10];
            scanf("%s",str);
            vs.push_back(str);        
        }
        sort(vs.begin(),vs.end(),cmp);
        bool bFirst = true;
        for(int i=0;i<vs.size();++i)
        {
            if(bFirst)
            {
                int a = atoi(vs[i].c_str());
                if(a==0 && i!= vs.size()-1) continue;
                printf("%d",a);    
                bFirst = false;
            }
            else
            {
                printf("%s",vs[i].c_str());
            }        
        }
        printf("\n");
    }
    
    return 0;
}
View Code

   1044題:如果暴力會超時,主要代碼中的bCanBreak的判斷,當里層循環遍歷到最后一個數字的時候,就直接跳出大循環。

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
#define INF (1<<30)
vector<int> vc;
map<int,int> res;
map<int,int> res2;
int main()
{
    int n,dst;
    scanf("%d%d",&n,&dst);
    for(int i=0;i<n;++i)
    {
        int a;
        scanf("%d",&a);
        vc.push_back(a);
    }
    int iMin = INF;
    bool bCanBreak = false;
    for(int i=0;i<n;++i)
    {
        int sum = 0;
        for(int j=i;j<n;++j)
        {
            sum += vc[j];
            if(sum == dst)
            {
                res[i+1] = j+1;
                break;
            }
            else if(sum > dst)
            {
                if(iMin > sum)
                {
                    iMin = sum;
                    res2.clear();
                }
                if(iMin == sum)
                {
                    res2[i+1] = j+1;
                }
                break;
            }
            if(j==n-1) bCanBreak = true;
        }
        if(bCanBreak) break;
    }
    if(res.size())
    {
        map<int,int>::iterator it = res.begin();
        for(;it != res.end();it++)
            printf("%d-%d\n",it->first,it->second);
    }
    else
    {
        map<int,int>::iterator it = res2.begin();
        for(;it != res2.end();it++)
            printf("%d-%d\n",it->first,it->second);
    }
    return 0;
}
View Code

   二刷的時候用的方法:計算res等於從第i個加到j個。然后每次減去第i個,發現res小於尋找的數時,加上j+1,j+2直到res>=尋找的數,然后重復以上步驟。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<climits>
#include<iterator>
using namespace std;
#define N (100010)
int n,m;
int a[N];
int minM = INT_MAX;
void print(int needm)
{
    int res = 0;
    for(int i=0,j=0;i<n;++i)
    {
        while(res < needm&&j<n)
            res += a[j++];
        if(res == needm)
        {
            printf("%d-%d\n",i+1,j);
            minM = needm;
        }
        else if(minM!=needm&&res>needm&&res<minM)
            minM = res;
        res -= a[i];
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("1.txt","r",stdin);
    #endif // ONLINE_JUDGE

    scanf("%d%d",&n,&m);

    for(int i=0;i<n;++i)
        scanf("%d",&a[i]);
    print(m);
    if(minM!=m)
    {
        print(minM);
    }
    return 0;
}
View Code

 

  1045題:變異的lcs,卡了一下

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
#define N (210)

int main()
{
    int n;
    bool bHave[N] = {false};
    int m,l,love[N];
    vector<int> vcColor;
    scanf("%d\n",&n);
    scanf("%d",&m);
    for(int i=0;i<m;++i)
    {
        scanf("%d",&love[i]);
        bHave[love[i]] = true;
    }
    scanf("%d",&l);
    for(int i=0;i<l;++i)
    {
        int a;
        scanf("%d",&a);
        if(bHave[a])
            vcColor.push_back(a);
    }
    n = vcColor.size();
    int dp[m+1][n+1];
    memset(dp,0,sizeof(dp));
    for(int i=0;i<m;++i)
        for(int j=0;j<n;++j)
        {
            if(love[i]==vcColor[j])
            {
                dp[i+1][j+1] = max(dp[i+1][j]+1,dp[i][j] + 1);
            }
            else
            {
                dp[i+1][j+1] = max(dp[i][j+1],dp[i+1][j]);
            }
        }
    printf("%d\n",dp[m][n]);
    return 0;
}
View Code

   1046題:如果是記錄每個點到下一個點的距離,然后用累加法會超時,應該是記錄每個點到起點的距離,然后相減就是他們之間的距離。同時要注意,假設a<b,a到b的距離有兩種可能性,一種是a到b,另一種是b到終點,然后在到a。

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

#define N (100010)

int main()
{
    int dis[N];
    int n;
    scanf("%d",&n);
    int len = 0;
    for(int i=0;i<n;++i)
    {
        int a;
        scanf("%d",&a);
        len += a;
        dis[i+1] = len;
    }
    int m;
    scanf("%d",&m);
    while(m--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        if(a > b) swap(a,b);
        int l = 0;
        if(a != b)
        {
            l = dis[b-1] - dis[a-1];
        }
        l = min(l,len-l);
        printf("%d\n",l);
    }
    return 0;
}
View Code

  1047題:不能用set存儲,最后一個case會超時,由於set每一次插入都會排一次序,使用vector來存儲,然后輸入結束后排一次序就可以了

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
#include<string>
#include<iterator>
using namespace std;
#define N (40010)
#define K (2510)

int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    vector<string> Course[k+1];
    for(int i=0;i<n;++i)
    {
        char name[5];
        int m;
        scanf("%s%d",name,&m);
        for(int j=0;j<m;++j)
        {
            int c;
            scanf("%d",&c);
            Course[c].push_back(name);
        }
    }
    for(int i=1;i<=k;++i)
    {
        printf("%d %d\n",i,Course[i].size());
        if(Course[i].size())
        {
            sort(Course[i].begin(),Course[i].end());
        }
        for(int j=0;j<Course[i].size();++j)
        {
            printf("%s\n",Course[i][j].c_str());
        }
    }
    return 0;
}
View Code

  1048題:面值可能會相等,比如 2 14 7 7輸出是 7 7

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<climits>
#include<iterator>
using namespace std;
#define N (100010)
int Hash[N];
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("1.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;++i)
    {
        int a;
        scanf("%d",&a);
        ++Hash[a];
    }
    for(int i=0;i<=m;++i)
    {
        if(Hash[i]&&Hash[m-i])
        {
            if(i==m-i&&Hash[i]==1) continue;
            printf("%d %d\n",i,m-i);
            return 0;
        }
    }
    printf("No Solution\n");
    return 0;
}
View Code

 

   1052題:dfs,有一個坑點,當起點是一個在圖中的值時,輸出一個是 0 -1;

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
#define N (100010)
struct Node
{
    int addr;
    int key;
    int nextaddr;
    Node()
    {
        nextaddr = -1;
        addr = -1;
    }
};

Node Map[N];
vector<Node> vc;
int n,iStart;
void dfs(int CurI)
{
    if(CurI == -1 || Map[CurI].addr==-1) return;
    Node curnode = Map[CurI];
    vc.push_back(curnode);
    dfs(curnode.nextaddr);
}
int cmp(const Node& n1,const Node& n2)
{
    return n1.key - n2.key < 0;
}
int main()
{
    scanf("%d%d",&n,&iStart);
    for(int i=0;i<n;++i)
    {
        Node node;
        scanf("%d%d%d",&node.addr,&node.key,&node.nextaddr);
        Map[node.addr] = node;
    }
    dfs(iStart);
    sort(vc.begin(),vc.end(),cmp);
    int nVcSize = vc.size();
    printf("%d",nVcSize);
    if(nVcSize) printf(" %05d",vc[0].addr);
    else printf(" -1");
    printf("\n");
    for(int i=0;i<nVcSize;++i)
    {
        printf("%05d %d ",vc[i].addr,vc[i].key);
        if(i != nVcSize-1)
        {
            printf("%05d\n",vc[i+1].addr);
        }
        else printf("-1\n");
    }
    return 0;
}
View Code

 

  1053題:簡單題,dfs,使用vector<vector<int> >存儲答案路徑,使用vector<int>[]存儲圖,然后在葉子節點加上一個結束節點,方便判斷。

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
#define N (110)
int w[N]={0};
int n,m,s;
vector<int> vcMap[N];
vector<vector<int> > vcPath;
void dfs(int CurI,int tw,vector<int> vc)
{
    if(CurI==n)
    {
        if(tw == s)
        {
            vcPath.push_back(vc);
        }
       return;
    }
    vc.push_back(w[CurI]);
    for(int i=0;i<vcMap[CurI].size();++i)
    {
        int NextI = vcMap[CurI][i];
        dfs(NextI,tw+w[CurI],vc);
    }
    vc.pop_back();
}
int cmp(const vector<int>& v1,const vector<int>& v2)
{
    for(int i=0;i<v1.size()&&i<v2.size();++i)
    {
        if(v1[i] != v2[i])
            return v1[i]-v2[i] > 0;
    }
    return 0;
}
int main()
{

    scanf("%d%d%d",&n,&m,&s);
    for(int i=0;i<n;++i)
        scanf("%d",&w[i]);
    for(int i=0;i<m;++i)
    {
        int a,k,b;
        scanf("%d%d",&a,&k);
        for(int j=0;j<k;++j)
        {
            scanf("%d",&b);
            vcMap[a].push_back(b);
        }
    }
    //方便判斷結束
    for(int i=0;i<n;++i)
        if(vcMap[i].size()==0) vcMap[i].push_back(n);
    vector<int> vc;
    dfs(0,0,vc);
    sort(vcPath.begin(),vcPath.end(),cmp);
    for(int i=0;i<vcPath.size();++i)
    {
        vector<int> &vc2 = vcPath[i];
        bool bFirst = true;
        for(int j=0;j<vc2.size();++j)
        {
            if(bFirst) bFirst = false;
            else printf(" ");
            printf("%d",vc2[j]);
        }
        printf("\n");
    }
    return 0;
}
View Code

    1055題:之前由於每次查詢都去排序導致超時,傻了

  

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
struct ST
{
    char name[10];
    int age;
    int net;
};
int cmp(const ST& st1,const ST& st2)
{
    if(st1.net != st2.net) return st1.net-st2.net > 0;
    if(st1.age != st2.age) return st1.age - st2.age < 0;
    return strcmp(st1.name,st2.name)<0;

}
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    vector<ST> vc;
    for(int i=0;i<n;++i)
    {
        ST st;
        scanf("%s%d%d",st.name,&st.age,&st.net);
        vc.push_back(st);
    }
    sort(vc.begin(),vc.end(),cmp);

    for(int i=0;i<k;++i)
    {
        int m,amin,amax;
        scanf("%d%d%d",&m,&amin,&amax);
        printf("Case #%d:\n",i+1);
        int iCnt = 0;
        for(int i=0;i<vc.size();++i)
        {
            if(iCnt == m)
            {
                break;
            }
            if(amin<=vc[i].age&&vc[i].age<=amax)
            {
                printf("%s %d %d\n",vc[i].name,vc[i].age,vc[i].net);
                ++iCnt;
            }
        }
        if(iCnt==0)
            printf("None\n");
    }
    return 0;
}
View Code

 

  1056題:不難,題目比較難理解:大致題意有np個老鼠,每次nc只一組選出最大的,最后不滿nc的算一組。反復,直到求得最大質量的老鼠。第二行輸入表示從0到np的老鼠質量,第三行輸入表示第幾只老鼠。

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
struct ST
{
    int i;
    int w;
    int iRank;
};
int cmp(const ST& st1,const ST& st2)
{
    return st1.i-st2.i<0;
}
int main()
{
    int np,nc;
    scanf("%d%d",&np,&nc);
    int w[np];
    ST st[np];
    vector<ST*> vc;
    vector<vector<ST*> > vcRes;
    for(int i=0;i<np;++i)
        scanf("%d",&w[i]);
    for(int i=0;i<np;++i)
    {
        scanf("%d",&st[i].i);
        st[i].w = w[st[i].i];
        vc.push_back(&st[i]);
    }
    while(vc.size()>1)
    {
        vector<ST*> vcTemp = vc;
        vc.clear();
        int i=0;
        vector<ST*> oneRes;
        while(i<vcTemp.size())
        {
            ST* bigone = NULL;
            for(int j=0;j<nc&&i<vcTemp.size();++j,++i)
            {
                if(bigone==NULL)
                {
                    bigone = vcTemp[i];
                }
                else if(bigone->w < vcTemp[i]->w)
                {
                    oneRes.push_back(bigone);
                    bigone = vcTemp[i];
                }
                else
                {
                    oneRes.push_back(vcTemp[i]);
                }
            }
            vc.push_back(bigone);
        }
        vcRes.push_back(oneRes);
    }
    int iCurRank = 1;
    if(vc.size())
        vc[0]->iRank = iCurRank++;
    for(int i=vcRes.size()-1;i>=0;--i)
    {
        for(int j=0;j<vcRes[i].size();++j)
            vcRes[i][j]->iRank = iCurRank;
        iCurRank += vcRes[i].size();
    }
    sort(st,st+np,cmp);
    for(int i=0;i<np;++i)
        if(i) printf(" %d",st[i].iRank);
        else  printf("%d",st[i].iRank);
    return 0;
}
View Code

   1057題:分塊搜索第k大的數字。

  

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
const char strPop[10] = "Pop";
const char strPush[10] = "Push";
const char strPeek[20] = "PeekMedian";
#define N (100010)
#define BLOCK  400
int block[400]={0};
int table[N]={0};
int FindK(int k)
{
    int cnt = 0;
    int i;
    for(i=0;i<400;++i)
    {
        if(cnt + block[i] >= k)
            break;
        cnt += block[i];
    }
    for(int j=i*BLOCK;j<N;++j)
    {
        cnt += table[j];
        if(cnt >= k)                //易錯(之前是cnt==k),最后兩個case就過不了了
            return j;

    }
    return 0;
}
int main()
{
    int n;
    scanf("%d",&n);
    vector<int> vc;
    for(int i=0;i<n;++i)
    {
        char cmd[20];
        scanf("%s",&cmd);
        if(strcmp(cmd,strPop)==0)
        {
            if(vc.size()==0)
            {
                printf("Invalid\n");
            }
            else
            {
                int key = vc[vc.size()-1];
                printf("%d\n",key);
                if(table[key]) --table[key];
                if(block[key/BLOCK]) --block[key/BLOCK];
                vc.pop_back();
            }
        }
        else if(strcmp(cmd,strPush)==0)
        {
            int num;
            scanf("%d",&num);
            vc.push_back(num);
            ++table[num];
            ++block[num/BLOCK];

        }
        else
        {
            if(vc.size()==0)
            {
                printf("Invalid\n");
            }
            else
            {
                int k = vc.size();
                int iMid = k%2==0 ? k/2 : (k+1)/2;
                int iRes = FindK(iMid);
                printf("%d\n",iRes);
            }
        }
    }
    return 0;
}
/*
17
Push 6
Push 6
Push 7
PeekMedian
*/
View Code

  1060題:題目還是挺難的,思路:

     1、刪除輸入數字之前的0,例如像00014這樣的數組

          2、尋找小數點的位置dot,如果沒有找到小數點,則位數等於字符串長度,如果找到了,位數等於dot。然后遍歷字符串,如果發現前導0則去掉,位數減一,如果發現小數點,位數不變。這種算法需要考慮特殊情況0,如果發現是0,則位數強制賦值成0,不然位數時-1。

          3、在第二步計算位置的同時並且去掉前導0和小數點,然后對剩下的數字進行n為輸出,不夠補0,超過截取。

   4、0可以表示成 0.000*10^3,so。。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
string getstr(string str,int m)
{
    int dot = str.find(".");
    int len = str.length();
    int wei = dot==-1?len:dot;
    string res = str;
    str = "";
    for(int i=0;i<len;++i)
    {
        if(res[i]=='0') --wei;
        else if(res[i]!='.')
        {
            res = res.substr(i,len-i);
            len = res.length();
            str = "";
            for(int j=0;j<len;++j)
                if(res[j]!='.') str+=res[j];
            break;
        }
    }

    len = str.length();
    if(len==0)  wei = 0;

    {
        res = "0.";
        int i;
        for(i=0;i<len&&i<m;++i)
            res += str[i];
        for(;i<m;++i)
            res += "0";
        char subfix[20];
        sprintf(subfix,"*10^%d",wei);
        res += subfix;
    }
    return res;
}
int main()
{
    #ifdef ONLINE_JUDGE
    #else
        freopen("test.txt","r",stdin);
    #endif
    int n;
    char str1[200],str2[200];
    scanf("%d%s%s",&n,str1,str2);
    string res1 = getstr(str1,n),res2=getstr(str2,n);
    if(strcmp(res1.c_str(),res2.c_str())==0)
        printf("YES %s\n",res1.c_str());
    else    printf("NO %s %s\n",res1.c_str(),res2.c_str());
    return 0;
}
View Code

 

 

    1061題:題目難懂,題目大致意思,第1個字符串和第2個字符串第一個共有字符表示哪一天(該字符要求A-F),第二個共同字符表示時間(0-9,A-N),第3個共同字符在第3和第4字符串中找(位置表示時間,0開始)

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
bool isEnglish(char c)
{
    if(c>='a'&&c<='z') return true;
    if(c>='A'&&c<='Z') return true;
    return false;
}
bool isBigEnglish(char c)
{
    if(c>='A'&&c<='Z') return true;
    return false;
}
bool isNum(char c)
{
    if(c>='0'&&c<='9') return true;
    return false;
}
int getPos(char c)
{
    if(c>='a'&&c<='z') return c-'a'+1;
    if(c>='A'&&c<='Z') return c-'A'+1;
    return 0;
}
int main()
{
    string weeks[] = {"","MON","TUE","WED","THU","FRI","SAT","SUN"};
    char s1[65],s2[65],s3[65],s4[65];
    scanf("%s%s%s%s",s1,s2,s3,s4);
    int week = 0,iWeek=0,h=0,m=0;
    int i;
    for(i=0;i<strlen(s1)&&i<strlen(s2);++i)
    {
        if(s1[i]==s2[i]&&isBigEnglish(s1[i])&&s1[i]<='G')
        {
            iWeek = i;
            week = getPos(s1[i]);
            week = (week-1)%7+1;
            break;
        }
    }

    for(i=i+1;i<strlen(s1)&&i<strlen(s2);++i)
    {
        if(s1[i]==s2[i]&&(isNum(s1[i])||(isBigEnglish(s1[i])&&s1[i]<='N')))
        {
            if(isNum(s1[i]))
            {
                h = s1[i]-'0';
            }
            else
            {
                h = s1[i]-'A'+10;
            }
            break;
        }
    }
    for(i=0;i<strlen(s3)&&i<strlen(s4);++i)
    {
        if(s3[i]==s4[i]&&isEnglish(s3[i]))
        {
            m = i;
            break;
        }
    }
    printf("%s %02d:%02d\n",weeks[week].c_str(),h,m);
    return 0;
}
View Code

  1063題:正常情況會超時,所以不能把交集和並集全求出來,只能求出交集個數,然后通過減法得到並集個數。2種解法:

  1、通過set_intersection函數求:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;
int main()
{
    int n,m;
    scanf("%d",&n);
    set<int> si[n];
    for(int i=0;i<n;++i)
    {
        scanf("%d",&m);
        for(int j=0;j<m;++j)
        {
            int temp;
            scanf("%d",&temp);
            si[i].insert(temp);
        }
    }
    int k;
    scanf("%d",&k);
    for(int i=0;i<k;++i)
    {
        int s,e;
        set<int> ss,st;
        scanf("%d%d",&s,&e);
        --s,--e;
        //交集
        set_intersection(si[s].begin(),si[s].end(),si[e].begin(),si[e].end(),
                         inserter(ss,ss.begin()));
        //並集
        /*set_union(si[s].begin(),si[s].end(),si[e].begin(),si[e].end(),
                         inserter(st,st.begin()));
        */
        int same = ss.size();
        int total = si[s].size()+si[e].size()-same;//st.size();
        if(total==0)   printf("0.0%%\n");
        else printf("%.1lf%%\n",100.0*same/total);

    }

    return 0;
}
View Code

       2、通過自己寫求交集的函數,具體實現看代碼

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
void getInsert(set<int> &in_set,const set<int> &s1,const set<int> &s2)
{
    set<int>::iterator it1 = s1.begin();
    set<int>::iterator it2 = s2.begin();
    while(it1!=s1.end()&&it2!=s2.end())
    {
        if(*it1==*it2)
        {
            in_set.insert(*it1);
            it1++;
            it2++;
        }
        else if(*it1 > *it2)     it2++;
        else      it1++;
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    set<int> s[n];
    for(int i=0;i<n;++i)
    {
        int m;
        scanf("%d",&m);
        for(int j=0;j<m;++j)
        {
            int a;
            scanf("%d",&a);
            s[i].insert(a);
        }
    }
    int k;
    scanf("%d",&k);
    for(int i=0;i<k;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        if(a==b) printf("0.00%%\n");
        else
        {
            --a;
            --b;
           set<int> si;
           getInsert(si,s[a],s[b]);
           double fRes = 100.0*si.size()/(s[a].size()+s[b].size()-si.size());
           printf("%.1lf%%\n",fRes);
        }
    }
    return 0;
}
View Code

   1065題:用long long判斷,通過判斷溢出來判斷大小,但是a+b的值需要用中間值保存,不然你只有可憐的12分。

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
#include<climits>
using namespace std;
int main()
{
    //freopen("test.txt","r",stdin);
    int T;
    scanf("%d",&T);
    for(int t=1;t<=T;++t)
    {
        long long int a,b,c;
        scanf("%lld%lld%lld",&a,&b,&c);
        bool bBig = true;
        /*
        錯誤,a+b需要賦值,具體為什么我也不知道
        if(a>0&&b>0&&a+b<=0) bBig = true;
        else if(a<0&&b<0&&a+b>=0) bBig = false;
        else bBig =a+b>c;
        */
        long long res = a+b;
        if(a>0&&b>0&&res<=0) bBig = true;
        else if(a<0&&b<0&&res>=0) bBig = false;
        else bBig =res>c;
        printf("Case #%d: %s\n",t,bBig?"true":"false");

    }
    return 0;
}
View Code

  很神奇的是用long double也能過(注意不是double)

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

int main()
{
    //freopen("test.txt","r",stdin);
    int T;
    scanf("%d",&T);
    for(int t=1;t<=T;++t)
    {
        long double a,b,c;
        scanf("%llf%llf%llf",&a,&b,&c);
        bool bBig = a+b>c;
        printf("Case #%d: %s\n",t,bBig?"true":"false");
    }
    return 0;
}
View Code

   1067題:0所在的b,b所在位置是b2,把0放到b2的位置,把b放到b的位置。數組a,a[b]=i表示數字b在i位置。不用去管他最小交換個數,當0交換到0位置后,如果沒有有序,則0先跟任意未排序好的數字交換位置,然后重復交換。用set保存未有序的數字。

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

int main()
{
    //freopen("test.txt","r",stdin);
    int n;
    scanf("%d",&n);
    int a[n],cnt=0;
    set<int> si;
    for(int i=0;i<n;++i)
    {
        int b;
        scanf("%d",&b);
        a[b] = i;
        if(b==i&&b) ++cnt;
        else if(b!=i&&b) si.insert(b);
    }
    int step=0;
    while(cnt < n-1)
    {
        if(a[0]==0)
        {
            int i = *(si.begin());
            if(a[i]!=i)
            {
                int b1 = a[i];  //i在b1位置
                a[0] = b1;  //0移到b1位置
                a[i] = 0;   //i移到0位置
            }

        }
        else
        {
            int b1 = a[0];  //0在b1位置
            int b2 = a[b1]; //b1在b2位置
            a[0] = b2;
            a[b1] = b1;
            si.erase(si.find(b1));
            ++cnt;
        }
        ++step;
    }
    printf("%d\n",step);
    return 0;
}
View Code

 

  1068題:01背包,主要找路徑時比較路徑序號小的判斷可能會搞錯。

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

bool cmp(vector<int> v1,vector<int> v2)
{
   for(int i=0;i<v1.size()&&i<v2.size();++i)
   {
       if(v1[i] != v2[i])
            return v1[i] > v2[i];
   }
   return false;
}
int main()
{
    //freopen("test.txt","r",stdin);
    int n,m;
    scanf("%d%d",&n,&m);
    int dp[m+1];
    vector<int> path[m+1];
    for(int i=0;i<=m;++i)
       dp[i] = -1;
    int c[n];
    for(int i=0;i<n;++i)
        scanf("%d",&c[i]);
    dp[0] = 0;
    sort(c,c+n);
    for(int i=0;i<n;++i)
    {
        for(int v=m;v>=c[i];--v)
            if(dp[v-c[i]]>=0)
            {
                if(dp[v] < dp[v-c[i]]+c[i])
                {
                    dp[v] = dp[v-c[i]]+c[i];
                    path[v] = path[v-c[i]];
                    path[v].push_back(c[i]);
                }
                if(dp[v] == dp[v-c[i]]+c[i]&&cmp(path[v],path[v-c[i]]))
                {
                    dp[v] = dp[v-c[i]]+c[i];
                    path[v] = path[v-c[i]];
                    path[v].push_back(c[i]);
                }

            }
    }
    if(dp[m] != m)
    {
        printf("No Solution\n");
    }
    else
    {
        for(int i=0;i<path[m].size();++i)
        {
            if(i) printf(" ");
            printf("%d",path[m][i]);
        }
    }
    return 0;
}
View Code

 

  1070題:不難,就是略坑,數量需要用double存儲,用int一個case過不了。 

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
typedef struct mooncake
{
   double num;
   double fprice;
};
int cmp(const mooncake& m1,const mooncake& m2)
{
    if(m1.num == 0)
    {
        return 1;
    }
    else if(m2.num == 0)
    {
        return 0;
    }
    return 1.0*m1.fprice/m1.num > 1.0*m2.fprice/m2.num;
}
int main()
{
    int n,d;
    scanf("%d%d",&n,&d);
    mooncake mc[n];
    for(int i=0;i<n;++i)
        scanf("%lf",&mc[i].num);
    for(int i=0;i<n;++i)
        scanf("%lf",&mc[i].fprice);
    sort(mc,mc+n,cmp);
    double sum = 0;
    int i = 0;
    while(d>=0&&i<n)
    {
        if(mc[i].num==0||mc[i].fprice==0)
        {

        }
        else if(d >= mc[i].num)
        {
            d -= mc[i].num;
            sum += mc[i].fprice;
        }
        else
        {
            sum += (mc[i].fprice*(1.0*d/mc[i].num));
            d = 0;
        }
        ++i;
    }
    printf("%.2lf\n",sum);
    return 0;
}
View Code

   

  1071題:惡心之處就在於不能在循環條件中使用strlen函數,否則超時

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
#define N (1048576+10)
bool isAlphanum(char c)
{
    if(c>='0'&&c<='9') return true;
    if(c>='a'&&c<='z') return true;
    if(c>='A'&&c<='Z') return true;
    return false;
}
char ToLower(char c)
{
    if(c>='A'&&c<='Z') c = 'a' + c-'A';
    return c;
}

int main()
{
    char str[N];
    fgets(str,sizeof(str),stdin);
    map<string,int> msi;
    int num = 0;
    string res = "";
    string word = "";
    int iStrLen = strlen(str);
    for(int i=0;i<iStrLen;++i)
    {
        char c = ToLower(str[i]);
        if(isAlphanum(c)==false) continue;
        word += c;
        if(isAlphanum(str[i+1])==false)
        {
            int tempcnt = ++msi[word];
            if((num==tempcnt&&word.length()<res.length())||num<tempcnt)
            {
                num = tempcnt;
                res = word;
            }
            word = "";
        }
    }
    if(res!="")
    {
        printf("%s %d\n",res.c_str(),num);
    }
    return 0;
}
View Code

 

   

  1072題:題目不好理解,不難。1、求每個gas到house的最短距離,求最短距離中的最大。如果相等,求平均距離最小的。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<map>
#include<set>
#include<algorithm>
#include<cstring>
#include<climits>
using namespace std;
#define N (1100)
int GetNo(char *str)
{
    int add = 0;
    if(str[0]=='G') ++str,add=1000;
    return add+atoi(str);
}
int n,m,k,ds;
int Map[N][N]={0};
int dp[N];
bool bVis[N];
void Dijkstra(int iStart)
{
    for(int i=1;i<N;++i)
        dp[i] = Map[iStart][i];
    for(int i=1;i<N;++i)
    {
        int iMindj = INT_MAX,iPos = iStart;
        for(int j=1;j<N;++j)
        {
            if(!bVis[j]&&iMindj>dp[j])
            {
                iMindj = dp[j];
                iPos = j;
            }
        }
        bVis[iPos] = true;
        if(dp[iPos] > ds) return;
        for(int j=1;j<N;++j)
        {
            //printf("dp[%d]=%d,dp[%d]=%d Map[%d][%d]=%d\n",j,dp[j],iPos,dp[iPos],iPos,j,Map[iPos][j]);
            if(!bVis[j]&&Map[iPos][j]!=INT_MAX&&dp[j]>dp[iPos]+Map[iPos][j])
            {
                dp[j] = dp[iPos] + Map[iPos][j];
                //printf("res=%d\n",dp[j]);
            }
        }
    }
}
int main()
{
    for(int i=0;i<N;++i)
        for(int j=0;j<N;++j)
            if(i==j)
                Map[i][j] = 0;
            else Map[i][j] = INT_MAX;
    scanf("%d%d%d%d",&n,&m,&k,&ds);
    for(int i=0;i<k;++i)
    {
        char str1[10],str2[10];
        int d;
        scanf("%s%s%d",str1,str2,&d);
        int a = GetNo(str1);
        int b = GetNo(str2);
        Map[a][b] = Map[b][a] = d;
    }
    int iMinSum = INT_MAX,iGas=-1,iMinPath=-1;
    for(int i=0;i<m;++i)
    {
        int gas = 1001+i;
        memset(bVis,0,sizeof(bVis));
        bVis[gas] = true;
        Dijkstra(gas);
        int j,Sum=0,iPath=INT_MAX;
        for(j=1;j<=n;++j)
        {
            //printf("gas=%d j=%d dp[j]=%d\n",gas,j,dp[j]);
            if(dp[j]>ds) break;
            Sum += dp[j];
            if(iPath > dp[j]) iPath = dp[j];
        }
        if(j > n && (iMinPath < iPath||(iMinPath == iPath && iMinSum > Sum)))
        {
            iGas = gas;
            iMinSum = Sum;
            iMinPath = iPath;
        }
    }
    if(iGas==-1) printf("No Solution\n");
    else
    {
        printf("G%d\n",iGas-1000);
        printf("%.1lf %.1lf\n",1.0*iMinPath,1.0*iMinSum/n);
    }
    return 0;
}
View Code

   1074題:稍微有點麻煩,dfs就可以了

  

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
#define N (100010)
struct ST
{
    int addr;
    int val;
    int nextaddr;
    ST()
    {
        nextaddr = -1;
    }
};
ST st[N];
bool bVis[N] = {true};
int iStart,n,k;
vector<int> res;
void travel(int iCurI,vector<int> vi)
{
    //printf("CurI=%05d\n",iCurI);
    if(iCurI==-1 || bVis[iCurI])
    {
        if(vi.size()==k)
        for(int i=vi.size()-1;i>=0;--i)
        {
            res.push_back(vi[i]);
        }
        else
        {
             for(int i=0;i<vi.size();++i)
            {
                res.push_back(vi[i]);
            }
        }
        return;
    }
    else if(vi.size()==k)
    {
        for(int i=vi.size()-1;i>=0;--i)
        {
            res.push_back(vi[i]);
        }
        vi.clear();
    }
    bVis[iCurI] = true;
    vi.push_back(iCurI);
    int iNextI = st[iCurI].nextaddr;
    travel(iNextI,vi);
}
int main()
{
    scanf("%d%d%d",&iStart,&n,&k);
    for(int i=0;i<n;++i)
    {
        int iaddr,v,inext;
        scanf("%d%d%d",&iaddr,&v,&inext);
        st[iaddr].val = v;
        st[iaddr].nextaddr = inext;
        st[iaddr].addr = iaddr;
        bVis[iaddr] = false;
    }
    vector<int> tempvi;
    travel(iStart,tempvi);
    for(int i=0;i<res.size();++i)
    {
        int ID = res[i];
        if(i != res.size()-1)
        {
            int iNextID = res[i+1];
            printf("%05d %d %05d\n",ID,st[ID].val,iNextID);
        }
        else
            printf("%05d %d -1\n",ID,st[ID].val);
    }
    return 0;
}
View Code

 

  1075題:題目說明不清楚,坑點:當得分是-1時,表示編譯未通過,在結果集中編譯未通過的輸出0,未提交的輸出 -,當參賽者沒有提交題目時,結果集中不輸出此用戶。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
#define K (6)
int prom[K]={100000000};
int n,k,m;
struct PAT
{
    int id;
    int grade[K];
    PAT()
    {
        for(int i=1;i<=k;++i)
            grade[i] = -2;
    }
    bool bUseful()
    {
        for(int i=1;i<=k;++i)
            if(grade[i]>=0) return true;
        return false;
    }
    int getSum() const
    {
        int sum = 0;
        for(int i=1;i<=k;++i)
            if(grade[i]>=0) sum+=grade[i];
        return sum;
    }
    int getPerfectNum() const
    {
        int res = 0;
        for(int i=1;i<=k;++i)
            if(grade[i]>=prom[i])
                ++res;
        return res;
    }
    void Print()
    {
        printf("%05d %d",id,getSum());
        for(int i=1;i<=k;++i)
            if(grade[i]==-1) printf(" 0");
            else if(grade[i]==-2) printf(" -");
            else printf(" %d",grade[i]);
        printf("\n");
    }
};
int cmp(const PAT& p1,const PAT& p2)
{
    if(p1.getSum()!=p2.getSum()) return p1.getSum()>p2.getSum();
    if(p1.getPerfectNum()!=p2.getPerfectNum()) return p1.getPerfectNum() > p2.getPerfectNum();
    return p1.id < p2.id;
}
map<int,PAT> mip;
vector<PAT> vc;
int main()
{
    scanf("%d%d%d",&n,&k,&m);
    for(int i=1;i<=k;++i)
        scanf("%d",&prom[i]);
    for(int i=0;i<m;++i)
    {
        int ID,proID,sorce;
        scanf("%d%d%d",&ID,&proID,&sorce);
        if(ID <= n)
        {
            PAT &pat = mip[ID];
            pat.id = ID;
            if(pat.grade[proID] < sorce)
            {
                pat.grade[proID] = sorce;
            }
        }
    }
    map<int,PAT>::iterator it = mip.begin();
    for(;it!=mip.end();it++)
    {
        if(it->second.bUseful())
        {
            vc.push_back(it->second);
        }
    }
    sort(vc.begin(),vc.end(),cmp);
    PAT temp;
    vc.push_back(temp);     //加入一個哨兵,便於判斷
    int iCurRank = 1;
    for(int i=0;i<vc.size()-1;++i)
    {
        printf("%d ",iCurRank);
        vc[i].Print();
        if(vc[i].getSum() != vc[i+1].getSum())
            iCurRank = i+2;
    }
    return 0;
}
View Code

   1077題:我以為是公有單詞的后綴,沒想到都不需要考慮是不是單詞,想得多反而錯誤了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
int main()
{
    vector<string> vs;
    int n;
    scanf("%d",&n);
    getchar();
    for(int i=0;i<n;++i)
    {
        char str[300];
        fgets(str,sizeof(str),stdin);
        vs.push_back(str);
    }
    vector<char> res;
    bool bOK = true;
    for(int i=0;i<300 && bOK;++i)
    {
        char c;
        for(int j=0;j<vs.size();++j)
        {
            int len = vs[j].length();
            int iCurI = len - i -1;
            if(iCurI < 0)
            {
                bOK = false;
                break;
            }
            if(vs[j][iCurI]==' ')
            {
                //考慮了單詞,其實空格也算公有的一部分
                //bOK = false;
                //break;
            }
            if(j==0) c = vs[j][iCurI];
            else if(vs[j][iCurI] != c)
            {
                bOK = false;
                break;
            }
        }
        if(bOK==true)
        {
            res.push_back(c);
        }
    }

    if(res.size()==1) printf("nai\n");
    else
    {
        for(int i=res.size()-1;i>=0;--i)
            if(res[i]!='\n') printf("%c",res[i]);
        printf("\n");
    }
    return 0;
}
View Code

   1088題:用就可以了long long

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
struct Fen
{
    long long int a;
    long long int b;
};
long long gcd(long long a,long long b)
{
    if(a < 0) a = -a;
    if(b < 0) b = -b;
    if(b==0) return a;
    return gcd(b,a%b);
}
long long bei(long long a,long long b)
{
    if(a < 0) a = -a;
    if(b < 0) b = -b;
    return a/gcd(a,b)*b;
}
int main()
{
    int n;
    scanf("%d",&n);
    vector<Fen> vc;
    for(int i=0;i<n;++i)
    {
        Fen fen;
        scanf("%lld/%lld",&fen.a,&fen.b);
        if(fen.a&&fen.b) vc.push_back(fen);
    }

    long long com = 1;
    for(int i=0;i<vc.size();++i)
    {
        com = bei(com,vc[i].b);
    }

    long long son = 0;
    for(int i=0;i<vc.size();++i)
    {
        son += com/vc[i].b*vc[i].a;
    }
    if(son == 0) printf("0\n");
    else
    {
        long long temp = gcd(son,com);
        son = son/temp;
        com = com/temp;
        bool bN = false;
        if(son > 0 && com <0 || son<0 && com>0)
        {
            bN = true;
            if(son<0) son = -son;
            if(com<0) com = -com;
        }
        if(son/com>0)
        {
            if(bN) printf("-");
            printf("%lld",son/com);
            son = son%com;
            if(son) printf(" ");
        }
        else if(bN) printf("-");
        if(son)
        {
            printf("%lld/%lld",son,com);
        }
        printf("\n");
    }
    return 0;
}
View Code

   1082題 108 yi Bai ling ba  1008 yi Qian ling ba

  

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
const int YI = 100000000;
const int WAN = 10000;
string strNum[] = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
void Print(long long int n)
{
    if(n>=1000)
    {
        printf("%s Qian",strNum[n/1000].c_str());
        n = n%1000;
        if(n)
        {
            printf(" ");
            if(n<100) printf("ling ");
        }
    }
    if(n>=100)
    {
        printf("%s Bai",strNum[n/100].c_str());
        n=n%100;
        if(n)
        {
            printf(" ");
            if(n<10) printf("ling ");
        }
    }
    if(n>=10)
    {
        printf("%s Shi",strNum[n/10].c_str());
        n = n%10;
        if(n) printf(" ");
    }
    if(n) printf("%s",strNum[n].c_str());
}
int main()
{
    long long int n;
    scanf("%lld",&n);
    if(n==0) printf("ling\n");
    else
    {
        if(n<0)
        {
            printf("Fu ");
            n = -n;
        }
        if(n>=YI)
        {
            printf("%s Yi",strNum[n/YI].c_str());
            n = n%YI;
            if(n)
                if(n<10000000) printf(" ling ");
                else printf(" ");
        }
        if(n>=WAN)
        {
            Print(n/WAN);
            printf(" Wan");
            n = n%WAN;
            if(n)
                if(n<1000) printf(" ling ");
                else printf(" ");
        }
        if(n) Print(n);
        printf("\n");
    }
    return 0;
}
View Code

 

  1084題:123 12這個容易錯

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
char toBig(char c)
{
    if('a'<=c&&c<='z') return c-'a'+'A';
    return c;
}
int main()
{
    char str1[100],str2[100];
    scanf("%s%s",str1,str2);
    int i=0,j=0;
    int len1=strlen(str1),len2=strlen(str2);
    string res="";
    set<char> sc;
    for(;i<len1;)
    {
        char c1 = toBig(str1[i]);
        char c2 = '@';
        if(j<len2)
        {
            c2 = toBig(str2[j]);
        }
        if(c1==c2) ++i,++j;
        else
        {
            if(sc.find(c1)==sc.end())
            {
                sc.insert(c1);
                res += c1;
            }
            ++i;
        }
    }
    printf("%s\n",res.c_str());
    return 0;
}
View Code

   1087題:容易超時

dfs的解法:

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
#include<climits>
using namespace std;
#define N (26*26*26+10)
int toNum(char* str)
{
    return (str[0]-'A')*26*26+(str[1]-'A')*26+(str[2]-'A');
}
int hap[N] = {0};
int Map[N][N];
bool bVis[N] = {false};
int n,k;
char strStart[4];
vector<int> vc[N];
string toStr(int n)
{
    char str[4]={'\0'};
    str[0] = n/26/26+'A';
    str[1] = n/26%26 + 'A';
    str[2] = n%26 + 'A';
    return str;
}
int iMaxHap = 0;
int iMinCost = INT_MAX;
int paths = 0;
int dst = toNum("ROM");
vector<int> vcRes;
void dfs(int iCurI,int iCost,int h,vector<int> v)
{
    //printf("%s cost=%d iMincost=%d h=%d iMaxHap=%d\n",toStr(iCurI).c_str(),iCost,iMinCost,h,iMaxHap);
    if(iCost == iMinCost && iCurI==dst)
    {
        ++paths;
    }
    else if(iCost < iMinCost && iCurI == dst)
    {
        paths = 1;
    }
    if(iCost > iMinCost ||
       (iCost==iMinCost&&h<iMaxHap) ||
       (iCost==iMinCost&&h==iMaxHap&&v.size()>vcRes.size())||
       (iCost==iMinCost&&h==iMaxHap&&v.size()==vcRes.size())/*這一行不加容易超時*/) return;
    if(iCurI==dst)
    {
        //printf("minCost=%d maxHap=%d\n",iMinCost,iMaxHap);
        vcRes = v;
        iMinCost = iCost;
        iMaxHap = h;
        return;
    }
    bVis[iCurI] = true;
    for(int i=0;i<vc[iCurI].size();++i)
    {
        int iNextI = vc[iCurI][i];
        if(!bVis[iNextI])
        {
            v.push_back(iNextI);
            dfs(iNextI,iCost+Map[iCurI][iNextI],h+hap[iNextI],v);
            v.pop_back();
        }
    }
    bVis[iCurI] = false;
}
int main()
{
    scanf("%d%d%s",&n,&k,strStart);
    for(int i=0;i<n-1;++i)
    {
        char str[4];
        int h;
        scanf("%s%d",str,&h);
        int iStr = toNum(str);
        hap[iStr] = h;
    }
    for(int i=0;i<k;++i)
    {
        char str1[4],str2[4];
        int a,b,len;
        scanf("%s%s%d",str1,str2,&len);
        a = toNum(str1);
        b = toNum(str2);
        //if(Map[a][b]==0)
        {
            vc[a].push_back(b);
            vc[b].push_back(a);
        }
        Map[a][b] = Map[b][a] = len;
    }
    vector<int> temp;
    temp.push_back(toNum(strStart));
    dfs(toNum(strStart),0,0,temp);
    if(vcRes.size()>1)
    {
        printf("%d %d %d %d\n",paths,iMinCost,iMaxHap,iMaxHap/(vcRes.size()-1));
    }
    for(int i=0;i<vcRes.size();++i)
    {
        if(i) printf("->");
        printf("%s",toStr(vcRes[i]).c_str());
    }
    printf("\n");
    return 0;
}
View Code

 dijkstra方法:不容易理解,而且容易出錯,但是效率高,自己把地名轉換成數字。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<climits>
#include<algorithm>
using namespace std;
#define N (210)
map<int,string> mis;
map<string,int> msi;
int n;
int H[N]={0};
bool bVis[N]={0};
int Map[N][N];
struct ST
{
    int cost;
    int hap;
    int pre;
    int cnt;
    int iStep;
    ST()
    {
        hap = 0;
        pre = 0;
        cnt = 1;
        iStep = 1;
    }
};
ST dp[N];
void dijstra()
{
    for(int i=0;i<n;++i)
    {
        dp[i].cost = Map[0][i];
        dp[i].hap = H[i];
    }

    for(int i=1;i<n;++i)
    {
        int minDj = INT_MAX,pos = 0;
        for(int j=1;j<n;++j)
        {
            if(!bVis[j]&&dp[j].cost < minDj)
            {
                minDj = dp[j].cost;
                pos = j;
            }
        }
        bVis[pos] = true;
        for(int j=1;j<n;++j)
        {
            if(!bVis[j]&&Map[pos][j]!=INT_MAX)
            {
                if(dp[j].cost > dp[pos].cost + Map[pos][j])
                {
                    dp[j].cost = dp[pos].cost + Map[pos][j];
                    dp[j].pre = pos;
                    dp[j].hap = dp[pos].hap + H[j];
                    dp[j].cnt = dp[pos].cnt;
                    dp[j].iStep = dp[pos].iStep+1;
                }
                else if(dp[j].cost == dp[pos].cost + Map[pos][j])
                {
                    dp[j].cnt += dp[pos].cnt;
                    if(dp[j].hap < dp[pos].hap+H[j])
                    {
                        dp[j].hap = dp[pos].hap+H[j];
                        dp[j].pre = pos;
                        dp[j].iStep = dp[pos].iStep+1;
                    }
                    else if(dp[j].hap == dp[pos].hap+H[j] && dp[j].iStep > dp[pos].iStep+1)
                    {
                        dp[j].pre = pos;
                        dp[j].iStep = dp[pos].iStep+1;
                    }
                }
            }
        }
    }
}
int main()
{
    int k;
    char strStart[4];
    scanf("%d%d%s",&n,&k,strStart);
    msi[strStart] = 0;
    mis[0] = strStart;
    for(int i=1;i<n;++i)
    {
        char str[4];
        scanf("%s%d",str,&H[i]);
        msi[str] = i;
        mis[i] = str;
    }
    for(int i=0;i<n;++i)
        for(int j=0;j<n;++j)
            if(i==j) Map[i][j] = 0;
            else Map[i][j] = INT_MAX;
    for(int i=0;i<k;++i)
    {
        char s1[4],s2[4];
        int cost;
        scanf("%s%s%d",s1,s2,&cost);
        int a1 = msi[s1],a2=msi[s2];
        Map[a1][a2] = Map[a2][a1] = cost;
    }
    int dst = msi["ROM"];
    dijstra();
    printf("%d %d %d %d\n",dp[dst].cnt,dp[dst].cost,dp[dst].hap,dp[dst].hap/dp[dst].iStep);
    vector<int> res;
    for(int i=dst;i!=0;i=dp[i].pre)
    {

        res.push_back(i);
    }
    res.push_back(0);
    bool bFirst = true;
    for(int i=res.size()-1;i>=0;--i)
    {
        if(bFirst) bFirst = false;
        else printf("->");
        printf("%s",mis[res[i]].c_str());
    }
    printf("\n");
    return 0;
}
View Code

      1088題:輸入也要簡化,只顧輸出化簡了,所以會有一個case過不了

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<climits>
#include<iterator>
using namespace std;
long long gcd(long long a,long long b)
{
    if(b==0) return a;
    return gcd(b,a%b);
}
string getstr(long long a)
{
    char str[100];
    sprintf(str,"%lld",a);
    return str;
}
struct Fen
{
    long long a;
    long long b;
    void change()
    {
        if(b==0) return;
        if(b<0) a = -a,b=-b;
        long long g = gcd(abs(a),b);
        a = a/g;
        b = b/g;
    }
    string gettext()
    {
        change();
        if(b==0)
        {
            return "Inf";
        }
        else if(a==0)
        {
            return "0";
        }
        long long ia = abs(a),ib = b;
        string res = "";
        if(a<0) res="(-";
        if(ib==1) res += getstr(ia);
        else
        {
            long long k = ia/ib;
            ia = ia%ib;
            if(k>0) res = res + getstr(k) + " ";
            res = res + getstr(ia) + "/" + getstr(ib);

        }
        if(a<0) res+=")";
        return res;
    }
};
Fen add(Fen f1,Fen f2)
{
    Fen f;
    f.a = f1.a*f2.b + f2.a*f1.b;
    f.b = f1.b*f2.b;
    return f;
}
Fen jian(Fen f1,Fen f2)
{
    Fen f;
    f.a = f1.a*f2.b - f2.a*f1.b;
    f.b = f1.b*f2.b;
    return f;
}
Fen cheng(Fen f1,Fen f2)
{
    Fen f;
    f.a = f1.a*f2.a;
    f.b = f1.b*f2.b;
    return f;
}
Fen chu(Fen f1,Fen f2)
{
    Fen f;
    f.a = f1.a*f2.b;
    f.b = f1.b*f2.a;
    return f;
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("1.txt","r",stdin);
    #endif // ONLINE_JUDGE
    Fen f1,f2;
    scanf("%lld/%lld",&f1.a,&f1.b);
    scanf("%lld/%lld",&f2.a,&f2.b);
    Fen f;
    f = add(f1,f2);
    printf("%s + %s = %s\n",f1.gettext().c_str(),f2.gettext().c_str(),f.gettext().c_str());
    f = jian(f1,f2);
    printf("%s - %s = %s\n",f1.gettext().c_str(),f2.gettext().c_str(),f.gettext().c_str());
    f = cheng(f1,f2);
    printf("%s * %s = %s\n",f1.gettext().c_str(),f2.gettext().c_str(),f.gettext().c_str());
    f = chu(f1,f2);
    printf("%s / %s = %s\n",f1.gettext().c_str(),f2.gettext().c_str(),f.gettext().c_str());

    return 0;
}
View Code

 

      1089題:case2是插入排序,。。。分治排序跟正常的2分分治不一樣。使用最暴力的解法就行了。case是這樣的比如2 1 3 4 5 9 8。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<climits>
#include<iterator>
using namespace std;
bool equalarr(int* a,int* b,int n)
{
    for(int i=0;i<n;++i)
        if(a[i]!=b[i]) return false;
    return true;
}
/*
1 2 3 4 9 7
1 2 3 4 9 7
*/
bool isInsert(int* a,int* b,int n)
{
    int temp[n];
    memcpy(temp,a,sizeof(temp));
    for(int i=2;i<=n;++i)
    {
        bool bEqu = equalarr(temp,b,n);
        sort(temp,temp+i);
        //比如1 2 3 4 9 7,你排到i=2的時候就相等了,但是我們期望的是i=5的時候。
        if(bEqu&&!equalarr(temp,b,n))
        {
            printf("Insertion Sort\n");
            for(int j=0;j<n;++j)
            {
                if(j) printf(" ");
                printf("%d",temp[j]);
            }
            return true;
        }
    }
    printf("Merge Sort\n");
    return false;
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("1.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int n;
    scanf("%d",&n);
    int a[n],b[n];
    for(int i=0;i<n;++i)
        scanf("%d",&a[i]);
    for(int i=0;i<n;++i)
        scanf("%d",&b[i]);
    bool bInsert = isInsert(a,b,n);
    if(!bInsert)
    {
        for(int len=2;;len*=2)
        {
            bool bequ = equalarr(a,b,n);
            for(int i=0;i<n;i+=len)
            {
                sort(a+i,a+min((i+len),n));
            }
            if(bequ)
            {
                for(int i=0;i<n;++i)
                {
                    if(i) printf(" ");
                    printf("%d",a[i]);
                }
                printf("\n");
                break;
            }
        }
    }
    return 0;
}
View Code

 

    1091題:用dfs會導致最后兩個是段錯誤,因為dfs在圖很大的時候回爆棧(遞歸太多)。數組如果是a[65][1300][130]會超時,a[1300][130][65]就會正常,注意了。使用非遞歸的bfs。其實我覺得像拓撲排序。

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int m,n,l,t;
int a[1300][130][65];
struct Point
{
    int l;
    int m;
    int n;
    Point(int l,int m,int n)
    {
        this->l = l;
        this->m = m;
        this->n = n;
    }
};
bool bOK(int curl,int curm,int curn)
{
    if(curl<0||curl>=l||curm<0||curm>=m||curn<0||curn>=n) return false;
    if(a[curm][curn][curl]==0) return false;
    return true;
}
int bfs(int curl,int curm,int curn)
{
    int cnt = 0;
    Point p(curl,curm,curn);
    if(bOK(p.l,p.m,p.n)==false) return 0;
    a[curm][curn][curl]=0;
    queue<Point> qi;
    qi.push(p);
    while(!qi.empty())
    {
        p = qi.front();
        qi.pop();
        ++cnt;
        if(bOK(p.l+1,p.m,p.n))
        {
            qi.push(Point(p.l+1,p.m,p.n));
            a[p.m][p.n][p.l+1] = 0;
        }
        if(bOK(p.l-1,p.m,p.n))
        {
            qi.push(Point(p.l-1,p.m,p.n));
            a[p.m][p.n][p.l-1] = 0;
        }
        if(bOK(p.l,p.m+1,p.n))
        {
            qi.push(Point(p.l,p.m+1,p.n));
            a[p.m+1][p.n][p.l] = 0;
        }
        if(bOK(p.l,p.m-1,p.n))
        {
            qi.push(Point(p.l,p.m-1,p.n));
            a[p.m-1][p.n][p.l] = 0;
        }
        if(bOK(p.l,p.m,p.n+1))
        {
            qi.push(Point(p.l,p.m,p.n+1));
            a[p.m][p.n+1][p.l] = 0;
        }
        if(bOK(p.l,p.m,p.n-1))
        {
            qi.push(Point(p.l,p.m,p.n-1));
            a[p.m][p.n-1][p.l] = 0;
        }

    }
    return cnt>=t?cnt:0;
}
int main()
{
    #ifdef ONLINE_JUDGE
    #else
        freopen("test.txt","r",stdin);
    #endif // ONLINE_JUDGE
    scanf("%d%d%d%d",&m,&n,&l,&t);
    for(int i=0;i<l;++i)
        for(int j=0;j<m;++j)
            for(int k=0;k<n;++k)
                scanf("%d",&a[j][k][i]);
    int res=0;
    for(int i=0;i<l;++i)
        for(int j=0;j<m;++j)
            for(int k=0;k<n;++k)
            {
                res += bfs(i,j,k);
            }
    printf("%d\n",res);
    return 0;
}
View Code

   1095題:模擬題,需要注意1:排序后,最接近的in和out一組,例如 in1,in2,out1,out2,in2和out1之間是這車在校園中逗留的時間,in1和out2是不符合規則的數據需要丟棄;2逗留時間是out2-out1,但是out2是不計入在學校的個數的。

  以下是是用hash的思想做的,用兩個hash數組記錄當前時間車子的數量,Ti[24*60*60]當前秒車子停的個數,Tm[24*60]當前分鍾車子的個數,因為光用ti一個會超時,所以我想如果in和out之間過大時,比如7:10:10到7:30:20出來,我不就可以這樣算,7:10:10到7:10:59,每次遍歷1秒,每次Ti加1;7:11:00到7:30:59每次遍歷1分鍾,每次Tm加1。最后7:30:00到7:30:19(最后一秒不算),每次遍歷1秒,Ti加1。所以h:m:s時車子的個數是:res = 60*60*h+60*m+s,個數=Ti[res]+Tm[res/60]

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
#define N (10010)
#define TN (24*60*60)
struct CarInOutTime
{
    int tick;
    bool bIn;
    CarInOutTime(int h,int m,int s,char* opt)
    {
        if(strcmp(opt,"in")==0) bIn = true;
        else bIn = false;
        tick = 60*60*h+60*m+s;
    }
};
int cmp(const CarInOutTime& t1,const CarInOutTime& t2)
{
    return t1.tick<t2.tick;
}
int Ti[TN];         //每秒鍾車的個數
int Tm[TN/60];      //每分鍾
struct Car
{
    string carid;//車牌
    vector<CarInOutTime> inouttime;   //出入時間
    int captime;                   //在校園中逗留的時間
    Car(){captime=0;}
    void Add(char* id,int h,int m,int s,char* opt)
    {
        carid = id;
        inouttime.push_back(CarInOutTime(h,m,s,opt));
    }
    void Deal()
    {
        sort(inouttime.begin(),inouttime.end(),cmp);    //排序
        int  intick;    //進入的人時間戳
        bool bhavein=false;       //前面是否進入過
        for(int i=0;i<inouttime.size();++i)
        {
            if(inouttime[i].bIn)
            {
                bhavein = true;
                intick = inouttime[i].tick;
            }
            else if(bhavein&&!inouttime[i].bIn)
            {
                bhavein = false;
                captime += inouttime[i].tick-intick;
                for(int tick=intick;tick<inouttime[i].tick;)
                {
                    if(tick%60==0&&tick+60<=inouttime[i].tick)
                    {
                        ++Tm[tick/60];   //因為這車在這一分鍾都在
                        tick += 60;
                    }
                    else  ++Ti[tick++];
                }
            }
        }
        inouttime.clear();//清空
    }
};
map<string,int> msi;    //把車的id轉換成編號(從0開始)
Car cars[N];
int main()
{
    #ifdef ONLINE_JUDGE
    #else
        freopen("test.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int n,k;
    scanf("%d%d",&n,&k);
    int carcnt = 0;
    for(int i=0;i<n;++i)
    {
        char carid[10],opt[5];
        int h,m,s;
        scanf("%s %d:%d:%d %s",carid,&h,&m,&s,opt);
        if(msi.find(carid)==msi.end())
            msi[carid] = carcnt++;
        cars[msi[carid]].Add(carid,h,m,s,opt);
    }
    vector<string> vs;//記錄逗留最長時間的車牌號
    int maxti = 0;
    for(int i=0;i<carcnt;++i)
    {
        cars[i].Deal();
        if(cars[i].captime >= maxti)
        {
            if(cars[i].captime > maxti) vs.clear(),maxti = cars[i].captime;
            vs.push_back(cars[i].carid);
        }
    }
    for(int i=0;i<k;++i)
    {
        int h,m,s;
        scanf("%d:%d:%d",&h,&m,&s);
        int tick = h*60*60+m*60+s;
        printf("%d\n",Ti[tick]+Tm[tick/60]);
    }
    sort(vs.begin(),vs.end());
    for(int i=0;i<vs.size();++i)
        printf("%s ",vs[i].c_str());
    printf("%02d:%02d:%02d\n",maxti/3600,maxti%3600/60,maxti%60);
    return 0;
}
View Code

 

  1096題:容易超時,已知最大的長度是12,你可以從2*3...*13,所以從len等於12開始累乘,發現積能被n整除則輸出,當len=1的時候需要判斷sum*sum是否大於n,否則會超時,b當sum*sum大於n時,說明該數時素數則必須另外輸出。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
using namespace std;
long long int getSum(int n,int len)
{
    long long int sum = 1;
    for(int i=0;i<len;++i)
        sum = sum*(n+i);
    return sum;
}
int main()
{
  int n;
  scanf("%d", &n);

  for(int len=12;len>=1;--len)
  {
      long long int sum;
      for(int i=2;(sum=getSum(i,len))<=n;++i)
      {
          //sum必須是long long否則撐起來會負數。
          if(len==1&&sum*sum > n)
          {
              break;
          }
          if(n%sum==0)
          {
              printf("%d\n",len);
              for(int j=0;j<len;++j)
              {
                  if(j) printf("*");
                  printf("%d",i+j);
              }
              return 0;
          }
      }
  }
  printf("1\n%d\n",n);
  return 0;
}
View Code

  1103題:dfs需要剪枝不然會超時,其實有點像N皇后的題目

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
int mypow(int n,int p)
{
    int res = 1;
    for(int i=0;i<p;++i)
    {
        res *= n;
    }
    return res;
}
int n,k,p,sum2=0;
bool bOK;
vector<int> res;
void dfs(int sum,int totalsum,int i,int len,vector<int> vi)
{
    //printf("totalsum=%d i=%d\n",totalsum,i);
    if(len==k)
    {
        if(sum==n)
        {
            if(sum2 < totalsum)
            {
                sum2 = totalsum;
                bOK = true;
                res = vi;
            }
        }
        return;
    }
    if(sum >= n)
    {
        return;
    }
    /*容易超時,過濾*/
    if(totalsum + (k-len)*i < sum2)
    {
        return;
    }
   
    for(int j = i;j>=1;--j)
    {
        vi.push_back(j);
        dfs(sum+mypow(j,p),totalsum+j,j,len+1,vi);
        vi.pop_back();
    }
}
int main()
{
    //freopen("test.txt","r",stdin);
    scanf("%d%d%d",&n,&k,&p);
    if(k==1)
    {
        int sum;
        for(int i=1;(sum=mypow(i,p))<=n;++i)
        {
            if(sum == n)
            {
                printf("%d = ",n);
                printf("%d^%d\n",i,p);
                return 0;
            }
        }
        printf("Impossible\n");
    }
    else
    {
        int sum,iMaxF = 0;
        for(int i=1;true;++i)
        {
            sum = mypow(i,p)+(k-1);
            if(sum >= n)
            {
                iMaxF = i;
                break;
            }
        }
        for(int i=iMaxF;i>=1;--i)
        {
            vector<int> vi;
            vi.push_back(i);
            dfs(mypow(i,p),i,i,1,vi);
        }
        if(bOK)
        {
            printf("%d = ",n);
            for(int i=0;i<res.size();++i)
            {
                if(i) printf(" + ");
                printf("%d^%d",res[i],p);
            }
            printf("\n");
        }
        else
            printf("Impossible\n");
    }
    return 0;
}
View Code

   1107題:並查集

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
#define H (1100)
int p[H];
int peo[H];     //記錄每個人的第一個愛好
int Find(int x)
{
    if(p[x]==x) return x;
    int root = Find(p[x]);
    p[x] = root;
    return root;
}
void Union(int x,int y)
{
    int a = Find(x);
    int b = Find(y);
    if(a!=b)
    {
        p[a] = b;
    }
}
int main()
{
    //freopen("test.txt","r",stdin);
    for(int i=0;i<H;++i)
        p[i] = i;
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;++i)
    {
        int k,pre;
        scanf("%d:",&k);
        for(int ik=0;ik<k;++ik)
        {
            int a;
            scanf("%d",&a);
            if(ik==0)
            {
                peo[i] = a;
            }
            else
            {
                Union(pre,a);
            }
            pre = a;
        }
    }
    map<int,int> mii;
    for(int i=0;i<n;++i)
        ++mii[Find(peo[i])];
    vector<int> vi;
    map<int,int>::iterator it = mii.begin();
    for(;it!=mii.end();it++)
        vi.push_back(it->second);
    sort(vi.begin(),vi.end());
    printf("%d\n",vi.size());
    for(int i=vi.size()-1;i>=0;--i)
    {
        if(i) printf("%d ",vi[i]);
        else printf("%d\n",vi[i]);
    }
    return 0;
}
View Code

  1109題:k行看成k列,然后總是錯誤

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
struct ST
{
    char name[10];
    int height;
};
int cmp(const ST &s1,const ST &s2)
{
    if(s1.height != s2.height) return s1.height > s2.height;
    return strcmp(s1.name,s2.name)<0;
}
void Print(ST* st,int istart,int len)
{
    string strname[len];
    int imid = (len)/2;
    strname[imid] = st[istart].name;
    for(int i=istart+1,j=1;i<istart+len;i += 2,++j)
    {
        if(i<istart+len)
            strname[imid-j] = st[i].name;
        if(i+1<istart+len)
            strname[imid+j] = st[i+1].name;
    }
    for(int i=0;i<len;++i)
    {
        if(i) printf(" ");
        printf("%s",strname[i].c_str());
    }
    printf("\n");
}
int main()
{
    //freopen("test.txt","r",stdin);
    int n,k;
    scanf("%d%d",&n,&k);
    ST st[n];
    for(int i=0;i<n;++i)
    {
        scanf("%s%d",st[i].name,&st[i].height);
    }
    sort(st,st+n,cmp);
    k = n/k;
    for(int i=0;i<n;)
    {
        int len = k;
        if(i==0)
        {
            len = (n>=k?k:0)+n%k;
        }
        Print(st,i,len);
        i += len;
    }
    return 0;
}
View Code

  1110題:進行bfs遍歷,每次遍歷完需要判斷該層是否是2的(level-1)次方,如果有下一層,而且該層不滿足2的level-1次方,說明不是bst(之前沒考慮所以錯了)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
#define N (100)
struct Node
{
    int key;
    Node *left;
    Node *right;
    Node(){left = right = NULL;}
};
Node nodes[N];
int  indegree[N]={0};
int cnt = 0;
Node* lastnode = NULL;
bool bVis[N] = {0};
void level_travel(vector<Node*> vn,int level)
{
    if(vn.size()==0) return;
    cnt += vn.size();
    vector<Node*> vnnext;
    for(int i=0;i<vn.size();++i)
    {
        Node* node = vn[i];
        if(node->left==NULL)
        {
           break;
        }
        if(bVis[node->left->key]) return;
        bVis[node->left->key] = true;
        vnnext.push_back(node->left);
        lastnode = node->left;
        if(node->right==NULL)
        {
            break;
        }
        if(bVis[node->right->key]) return;
        bVis[node->right->key] = true;
        vnnext.push_back(node->right);
        lastnode = node->right;
    }

    if(vnnext.size())
    {
        int stdcnt = 1;
        for(int i=1;i<level;++i)
        {
            stdcnt *= 2;
        }
        if(stdcnt != vn.size())
        {
            return;
        }
        level_travel(vnnext,level+1);
    }
}
int main()
{
    //freopen("test.txt","r",stdin);
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;++i)
    {
        char cl[5],cr[5];
        scanf("%s%s",cl,cr);
        nodes[i].key = i;
        if(cl[0]!='-')
        {
            nodes[i].left = &nodes[atoi(cl)];
            ++indegree[atoi(cl)];
        }
        if(cr[0]!='-')
        {
            nodes[i].right = &nodes[atoi(cr)];
            ++indegree[atoi(cr)];
        }
    }
    Node* root = NULL;
    for(int i=0;i<n;++i)
    {
        if(indegree[i]==0)
        {
            root = &nodes[i];
            break;
        }
    }
    vector<Node*> vn;
    lastnode = root;
    bVis[root->key] = true;
    vn.push_back(root);
    level_travel(vn,1);
    if(cnt == n)
    {
        printf("YES %d\n",lastnode->key);
    }
    else
    {
        printf("NO %d\n",root->key);
    }
    return 0;
}
View Code

  1111題:dfs會超時,最多只能27分。只能用dijkstra,並且使用pre數組記錄路徑。寫了40分鍾淚崩。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
#define N (510)
#define INF (1<<30)
int Dis[N][N];
int Tim[N][N];
bool bVis[N];
int startpos,endpos;
int n,m;
int resDis;
vector<int> vcDis;
int resTim;
vector<int> vcTim;
void dijkstraDis()
{
    memset(bVis,0,sizeof(bVis));
    int dp[n];
    int fast[n];
    int pre[n];
    for(int i=0;i<n;++i)
    {
        dp[i] = Dis[startpos][i];
        fast[i] = Tim[startpos][i];
        pre[i] = startpos;
    }
    bVis[startpos] = true;
    for(int i=0;i<n;++i)
    {
        int mindj=INF,minti=INF,pos = startpos;
        for(int j=0;j<n;++j)
        {
            if(!bVis[j]&&(dp[j]<mindj||
                          dp[j]==mindj&&fast[j]<minti))
            {
                mindj = dp[j];
                minti = fast[j];
                pos = j;
            }
        }
        bVis[pos] = true;
        for(int j=0;j<n;++j)
        {
            if(!bVis[j] && (dp[j] > dp[pos]+Dis[pos][j] ||
                                dp[j] == dp[pos]+Dis[pos][j]&&fast[j] > fast[pos]+Tim[pos][j]))
            {
                pre[j] = pos;
                dp[j] = dp[pos]+Dis[pos][j];
                fast[j] = fast[pos]+Tim[pos][j];
            }
        }
        if(bVis[endpos])
        {
            resDis = dp[endpos];
            for(int j=endpos;true;j=pre[j])
            {
                vcDis.push_back(j);
                if(j==startpos)
                {
                    break;
                }
            }
            reverse(vcDis.begin(),vcDis.end());
            return;
        }
    }
}
void dijkstraTim()
{
    memset(bVis,0,sizeof(bVis));
    int dp[n];
    int ins[n];
    int pre[n];
    for(int i=0;i<n;++i)
    {
        dp[i] = Tim[startpos][i];
        ins[i] = 0;
        pre[i] = startpos;
    }
    bVis[startpos] = true;
    for(int i=0;i<n;++i)
    {
        int mindj=INF,minins=INF,pos = startpos;
        for(int j=0;j<n;++j)
        {
            if(!bVis[j]&&(dp[j]<mindj||
                          dp[j]==mindj&&ins[j]<minins))
            {
                mindj = dp[j];
                minins = ins[j];
                pos = j;
            }
        }
        bVis[pos] = true;
        for(int j=0;j<n;++j)
        {
            if(!bVis[j] && (dp[j] > dp[pos]+Tim[pos][j] ||
                                dp[j] == dp[pos]+Tim[pos][j]&&ins[j] > ins[pos]+1))
            {
                pre[j] = pos;
                dp[j] = dp[pos]+Tim[pos][j];
                ins[j] = ins[pos]+1;
            }
        }
        if(bVis[endpos])
        {
            resTim = dp[endpos];
            for(int j=endpos;true;j=pre[j])
            {
                vcTim.push_back(j);
                if(j==startpos)
                {
                    break;
                }
            }
            reverse(vcTim.begin(),vcTim.end());
            return;
        }
    }
}
bool isVecSame(vector<int> v1,vector<int> v2)
{
    if(v1.size()!= v2.size()) return false;
    for(int i=0;i<v1.size();++i)
    {
        if(v1[i] != v2[i]) return false;
    }
    return true;
}
int main()
{
    //freopen("test.txt","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;++i)
        for(int j=0;j<n;++j)
        {
            if(i==j)
            {
                Dis[i][j] = Tim[i][j] = 0;
            }
            else
            {
                Dis[i][j] = Tim[i][j] = INF;
            }
        }
    for(int i=0;i<m;++i)
    {
        int v1,v2,oneway,len,tim;
        scanf("%d%d%d%d%d",&v1,&v2,&oneway,&len,&tim);
        Dis[v1][v2] = len;
        Tim[v1][v2] = tim;
        if(oneway==0)
        {
            Dis[v2][v1] = len;
            Tim[v2][v1] = tim;
        }
    }
    scanf("%d%d",&startpos,&endpos);
    dijkstraDis();
    dijkstraTim();
    if(isVecSame(vcDis,vcTim))
    {
        printf("Distance = %d; Time = %d: ",resDis,resTim);
        for(int i=0;i<vcDis.size();++i)
        {
            if(i) printf(" -> ");
            printf("%d",vcDis[i]);
        }
        printf("\n");
    }
    else
    {
        printf("Distance = %d: ",resDis);
        for(int i=0;i<vcDis.size();++i)
        {
            if(i) printf(" -> ");
            printf("%d",vcDis[i]);
        }
        printf("\n");
        printf("Time = %d: ",resTim);
        for(int i=0;i<vcTim.size();++i)
        {
            if(i) printf(" -> ");
            printf("%d",vcTim[i]);
        }
        printf("\n");
    }
    return 0;
}
View Code

  1117題:題意有點坑,具體題意解釋在代碼注釋中

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
int cmp(const int& a,const int& b)
{
    return a>b;
}
//題目不好理解,是從給出的序列中選出最大的E,滿足E天每天騎行距離都大於E。(不用按順序)
int main()
{
    //freopen("test.txt","r",stdin);
    int n;
    scanf("%d",&n);
    int a[n];
    for(int i=0;i<n;++i)
    {
        scanf("%d",&a[i]);
    }
    sort(a,a+n,cmp);
    for(int len=n;len>=1;--len)
    {
        if(a[len-1]>len)
        {
            printf("%d\n",len);
            return 0;
        }
    }
    printf("0\n");
    return 0;
}
View Code

    1119題:有先序和后序求中序,題目很新穎,光想不太容易想清楚,最后畫圖和編碼一起這樣方便找規律。什么時候二叉樹不唯一,什么時候唯一呢?那例題來說1 2 3 4 6 7 5和2 6 7 4 5 3 1,我們第一步可以得到當前父節點1。然后如何判斷左右孩紙呢。

先序1后面那個就是下一個節點(2),后序1前面那個就是下一個節點(3),這時候你發現2和3不一樣,說明什么呢--其實說明一個是左孩紙,一個是有孩紙。然后從先序中找右孩紙(3)的節點位置,然后我們可以找到左右孩紙的兩顆樹的序:左孩紙樹的先序序列2,后序也是2,右孩紙的先序序列就是3 4 6 7 5,后序序列是6 7 4 5 3。然后不斷重復以上步驟就好了。

再看另一個例子:1 2 3 4、2 4 3 1。為什么不唯一呢,找左右孩紙序列,左孩紙2 右孩紙3 4(先序),4 3(后序)。然后對右孩紙進行遞歸,你會發現根節點是3,孩紙節點只有一個(4),然后你就不知道他是屬於左節點還是右節點了,所以不唯一。

所以結論:先序和后序求中序,要求必須是孩紙節點要么沒有,要么是2個,不能有任意節點只有一個孩紙節點。

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
struct Node
{
    int key;
    Node* left;
    Node* right;
    Node()
    {
        left = right = NULL;
    }
};
bool bOnly = true;
Node* CreateTree(int* pre,int *post,int len)
{
    Node *node = new Node();
    node->key = *pre;
    if(len != 1)
    {
        //printf("len=%d\n",len);
        if(*(pre+1) == *(post+len-2))
        {
            bOnly = false;
            node->left = CreateTree(pre+1,post,len-1);
        }
        else
        {
            int rightkey = *(post+len-2);
            int rightindex = 0;
            for(;rightindex<len;++rightindex)
            {
                if(rightkey == *(pre+rightindex))
                {
                    break;
                }
            }
            node->left = CreateTree(pre+1,post,rightindex-1);
            node->right = CreateTree(pre+rightindex,post+rightindex-1,len-rightindex);
        }
    }
    return node;
}
bool bFirst = true;
void inorder_travel(Node* root)
{
    if(root == NULL) return;
    inorder_travel(root->left);
    if(bFirst) bFirst = false;
    else printf(" ");
    printf("%d",root->key);
    inorder_travel(root->right);
}
int main()
{
    //freopen("test.txt","r",stdin);
    int n;
    scanf("%d",&n);
    int pre[n],post[n];
    for(int i=0;i<n;++i)
        scanf("%d",&pre[i]);
    for(int i=0;i<n;++i)
        scanf("%d",&post[i]);
    Node* root = CreateTree(pre,post,n);
    if(bOnly)
    {
        printf("Yes\n");
    }
    else
    {
        printf("No\n");
    }
    inorder_travel(root);
    printf("\n");
    return 0;
}
View Code

   1125題意還是搞錯了。。。可以再做一遍看看。最后的四舍五入那一個可以忽略,好像沒有case卡這個,直接轉換成整型就行了。(可能他的case都是剛好整除的吧)

   1126題:1)題意比較繞,想復雜了;2)遍歷所有節點判斷錯了。

  

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define N (510)
int n,m;
int Map[N][N];
int indegree[N];
bool bVis[N];
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);
        }
    }
}
/*給定一個圖,計算該圖的每個結點的度
    若所有的節點的度均為偶數則為“Eulerian”,
    若恰好有兩個為奇數則為“Semi-Eulerian”,
    其他為“Non-Eulerian”。
    需要判斷是否是連通圖。
    */
int main()
{
    //freopen("test.txt","r",stdin);
    scanf("%d%d",&n,&m);
    memset(Map,0,sizeof(Map));
    memset(indegree,0,sizeof(indegree));
    memset(bVis,0,sizeof(bVis));
    for(int i=0;i<m;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        Map[a][b] = Map[b][a] = 1;
        ++indegree[a];
        ++indegree[b];
    }
    int iOddnum=0;
    for(int i=1;i<=n;++i)
    {
        if(indegree[i]%2)
        {
            ++iOddnum;
        }
        if(i>1) printf(" ");
        printf("%d",indegree[i]);
    }
    printf("\n");
    bVis[1] = true;
    dfs(1,1);
    if(sum==n)
    {
        if(iOddnum==0) printf("Eulerian\n");
        else if(iOddnum==2) printf("Semi-Eulerian\n");
        else printf("Non-Eulerian\n");
    }
    else
    {
        printf("Non-Eulerian\n");
    }

    return 0;
}
View Code

   1131:題:簡單dfs,剛開始理解錯誤,以為有公共線路,后來發現沒有。最后一個case容易超時,是因為你把數組開太大。line[N][N],可以用map代替,key = i+j*N;

 #include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
#define N (10010)
struct ST
{
    int start;
    int stop;
    int line;
};
vector<int> vcMap[N];
//int line[N][N];
map<int,int> line;
bool bVis[N];
int iMinLen = N;
vector<ST> vs;
int iStartStop,iEndStop;
void dfs(int curI,int len,vector<ST>vi)
{
    if(curI==iEndStop)
    {
        if(len < iMinLen)
        {
            iMinLen = len;
            vs = vi;
        }
        else if(len==iMinLen&&vs.size()>vi.size())
        {
           vs = vi;
        }
        return;
    }
    if(len >= iMinLen) return;
    for(int i=0;i<vcMap[curI].size();++i)
    {
        int nextI = vcMap[curI][i];

        if(!bVis[nextI])
        {
            bVis[nextI] = true;
            int curLine = line[curI+nextI*N];
            bool bNeedAdd = true;
            if(vi.size()&&vi[vi.size()-1].line==curLine)
            {
                bNeedAdd = false;
            }

            if(bNeedAdd)
            {
                ST st;
                st.line = curLine;
                st.start = curI;
                st.stop =  nextI;
                vi.push_back(st);
            }
            else
            {
                vi[vi.size()-1].stop = nextI;
            }
            dfs(nextI,len+1,vi);
            if(bNeedAdd)
                vi.pop_back();
            else
            {
                vi[vi.size()-1].stop = curI;
            }
            bVis[nextI] = false;
        }
    }
}
int main()
{
    //freopen("test.txt","r",stdin);
    int n;
    scanf("%d",&n);
    int prestop;
    for(int i=0;i<n;++i)
    {
        int m;
        scanf("%d",&m);
        for(int j=0;j<m;++j)
        {
            int a;
            scanf("%d",&a);
            if(j==0) prestop = a;
            else
            {
                vcMap[prestop].push_back(a);
                vcMap[a].push_back(prestop);
                line[prestop+a*N] = i+1;
                line[a+prestop*N] = i+1;
                prestop = a;
            }
        }
    }
    int k;
    scanf("%d",&k);
    for(int i=0;i<k;++i)
    {
        memset(bVis,0,sizeof(bVis));
        iMinLen = N;
        scanf("%d%d",&iStartStop,&iEndStop);
        bVis[iStartStop] = 1;
        vs.clear();
        vector<ST> vi;
        dfs(iStartStop,0,vi);
        printf("%d\n",iMinLen);
        for(int j=0;j<vs.size();++j)
        {
            printf("Take Line#%d from %04d to %04d.\n",vs[j].line,vs[j].start,vs[j].stop);
        }
    }
    return 0;
}
View Code

 


免責聲明!

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



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