pat

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0)break;

        int i,j;
        int sum=0;
        for(i=1;i<=n;i++){
            sum+=i;
            // sum=sum+i;
            // sum-=i;
        }
        if(sum==m)
        {
            printf("%d\n",sum);
        }
        else if(sum<m)
        {
            printf("%d\n",m);
        }
        else {
            printf("%d\n",sum+m);
        }
    }
    return 0;
}




zoj1456 凸包

http://blog.youkuaiyun.com/l04205613/article/details/6401402

 

 

PAT1038 Recover the Smallest Number

由一道面试题改的   把数组排成最小的数

 

不同之处是这个是直接按字符串处理的

 

Sample Input:

5 32 321 3214 0229 87
Sample Output:
22932132143287
 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<map>
#define N 10010
#define INF 0x7fffffff
using namespace std;
string s[N];
bool cmp(string a,string b)
{
    return a+b<b+a;
}
int main()
{
    int  n,i;
    while(~scanf("%d",&n))
    {
        char ch[10];
        for(i=0;i<n;i++){
              scanf("%s",ch);
              s[i]=ch;
        }
        sort(s,s+n,cmp);
        string res="";
        for(i=0;i<n;i++)res+=s[i];
        i=0;
        while(res[i]=='0')i++;
        if(i==res.length())puts("0");
        else {
            puts(res.substr(i,res.length()-i).c_str());
        }
    }
    return 0;
}


【百度面试题】把数组排成最小的数

问题描述:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。例如输入数组{32,  321},则输出这两个能排成的最小数字32132。请给出解决问题的算法,并证明该算法。

      思路:先将整数数组转为字符串数组,然后字符串数组进行排序,最后依次输出字符串数组即可。这里注意的是字符串的比较函数需要重新定义,不是比较a和b,而是比较ab与 ba。如果ab < ba,则a < b;如果ab > ba,则a > b;如果ab = ba,则a = b。比较函数的定义是本解决方案的关键。这道题其实就是希望我们能找到一个排序规则,根据这个规则排出来的数组能排成一个最小的数字。

      证明:为什么这样排个序就可以了呢?简单证明一下。根据算法,如果a < b,那么a排在b前面,否则b排在a前面。可利用反证法,假设排成的最小数字为xxxxxx,并且至少存在一对字符串满足这个关系:a > b,但是在组成的数字中a排在b前面。根据a和b出现的位置,分三种情况考虑:

      (1)xxxxab,用ba代替ab可以得到xxxxba,这个数字是小于xxxxab,与假设矛盾。因此排成的最小数字中,不存在上述假设的关系。

      (2)abxxxx,用ba代替ab可以得到baxxxx,这个数字是小于abxxxx,与假设矛盾。因此排成的最小数字中,不存在上述假设的关系。

      (3)axxxxb,这一步证明麻烦了一点。可以将中间部分看成一个整体ayb,则有ay < ya,yb < by成立。将ay和by表示成10进制数字形式,则有下述关系式,这里a,y,b的位数分别为n,m,k。

        关系1: ay < ya => a * 10^m + y < y * 10^n + a => a * 10^m - a < y * 10^n - y => a( 10^m - 1)/( 10^n - 1) < y

        关系2: yb < by => y * 10^k + b < b * 10^m + y => y * 10^k - y < b * 10^m - b => y < b( 10^m -1)/( 10^k -1) 

        关系3: a( 10^m - 1)/( 10^n - 1) < y < b( 10^m -1)/( 10^k -1)  => a/( 10^n - 1)< b/( 10^k -1) => a*10^k - a < b * 10^n - b =>a*10^k + b < b * 10^n + a => a < b

       这与假设a > b矛盾。因此排成的最小数字中,不存在上述假设的关系。

       综上所述,得出假设不成立,从而得出结论:对于排成的最小数字,不存在满足下述关系的一对字符串:a > b,但是在组成的数字中a出现在b的前面。从而得出算法是正确的。


1039. Course List for Student (25)


这题的学生数N不止40000  ,坑, 直接用map 去查找string对应的容器标超时,非要用hash,也真是够了,66666 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<map>
#include<vector>
#define INF 0x7fffffff
using namespace std;
const int MAX_STU = 26*26*26*10+10;
vector<int>a[MAX_STU];
int hashName(const char * name){
    return (name[0]-'A')*26*26*10+(name[1]-'A')*26*10+(name[2]-'A')*10+(name[3]-'0');
}
int main()
{
    int n,m,num;
    char na[5];
    while(~scanf("%d%d",&n,&m))
    {
        num=0;
        for(int i=0;i<=MAX_STU;i++)a[i].clear();
        while(m--)
        {
            int cur,stu;
            scanf("%d%d",&cur,&stu);
            while(stu--){
                scanf("%s",na);
                a[hashName(na)].push_back(cur);
              //  if(num>40001)while(1);
            }
        }
        for(int i=0;i<=MAX_STU;i++)sort(a[i].begin(),a[i].end());
        while(n--)
        {
            scanf("%s",na);
            printf("%s",na);
            int p=hashName(na);
            printf(" %d",a[p].size());
            for(int i=0;i<a[p].size();i++)printf(" %d",a[p][i]);
            puts("");

        }
    }

    return 0;
}


pat1042 感觉可以改编成一道找规律的题


PAT1014

容易出错的地方:是在17:00及以后开始服务的客户输出"Sorry",而不是17:00之前结束服务的输出"Sorry";

过了下面两个例子就好了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#define INF 0x7fffffff
#define N 500000
using namespace std;
int n,m,k,Q;
struct ss
{
    int id;
    int cost;
    int endtime;
}t;
queue<ss>q[30],que;
int timer[30];
int getqueue()
{
    int mi=20;
    for(int i=1;i<=n;i++)if(q[i].size()<mi)mi=q[i].size();
    if(mi>=m)return -1;
    for(int i=1;i<=n;i++)if(q[i].size()==mi)return i;
}
int main()
{
    while(~scanf("%d%d%d%d",&n,&m,&k,&Q))
    {
        for(int i=1;i<=n;i++)while(!q[i].empty())q[i].pop();
        while(!que.empty())que.pop();
        for(int i=1;i<=n;i++)timer[i]=8*60;
        for(int i=1;i<=k;i++)
        {
            t.id=i;
            scanf("%d",&t.cost);
            int p=getqueue();
            if(p==-1)que.push(t);
            else {
                    timer[p]+=t.cost;
                    t.endtime=timer[p];
                    q[p].push(t);
            }
        }
        int ans[1010];
        memset(ans,-1,sizeof(ans));
        for(int T=8*60;T<=17*60;T++)
        {
            for(int i=1;i<=n;i++)
            {
                t=q[i].front();
                if(t.endtime==T){
                    ans[t.id]=t.endtime;
                  //  printf(" -- %d %d %d\n",t.id,t.cost,t.endtime-480);
                    q[i].pop();
                  /*
                  不存在t.cost=0
                  while(!q[i].empty()&&q[i].front().endtime==T){
                        ans[q[i].front().id]=t.endtime;
                        q[i].pop();
                    }
                    */
                }
            }
            int p;
            while(!que.empty()&&(p=getqueue())!=-1)
            {
                t=que.front();
                que.pop();
                timer[p]+=t.cost;
                t.endtime=timer[p];
              //  printf(" **%d %d %d %d\n",p,t.id,t.cost,t.endtime-480);
                q[p].push(t);
            }
        }
        for(int i=1;i<=n;i++)if(!q[i].empty()){
            t=q[i].front();
            if(t.endtime-t.cost<17*60)ans[t.id]=t.endtime;
        }
        int x;
        while(Q--)
        {
            scanf("%d",&x);
            if(ans[x]==-1)puts("Sorry");
            else printf("%02d:%02d\n",ans[x]/60,ans[x]%60);
        }
    }
    return 0;
}
/*
2 2 7 7
550 250 250 4 3 533 200
1 2 3 4 5 6 7

2 2 7 5
1 2 6 4 3 533 2
3 4 5 6 7


*/

ZOJ 1344

吃t

不清楚人一直在原地时应该怎么做?

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,x1,y1,x2,y2,x3,y3,d;
char act[55];
char mapp[55][55],dogsight[55][55],vis[55][55];
int dy[4]={0,-1,0,1};
int dx[4]={-1,0,1,0};
int ans;
struct ss
{
    int x,y;
    int t;
}dog[55];
queue<ss>q;
void getdogsight(int t)
{
    t=t%d;
    int x=dog[t].x;
    int y=dog[t].y;
    int direct=dog[t].t;
    memset(dogsight,0,sizeof(dogsight));
   // printf("getdogsight %d %d %d\n",x,y,direct);
    if(direct==0){
            for(int i=x;i>=1;i--){
                    if(mapp[i][y]=='*')break;
                    dogsight[i][y]=1;
            }
    }
    else if(direct==1){
            for(int i=y;i>=1;i--){
                    if(mapp[x][i]=='*')break;
                    dogsight[x][i]=1;
            }
    }
    else if(direct==2){
            for(int i=x;i<=n;i++){
                    if(mapp[i][y]=='*')break;
                    dogsight[i][y]=1;
            }
    }
    else {
            for(int i=y;i<=m;i++){
                    if(mapp[x][i]=='*')break;
                    dogsight[x][i]=1;
            }
    }
    /*
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)printf("%d",dogsight[i][j]);
        printf("\n");
    }
    */
}
int judside(int x,int y)
{
    if(x>=1&&x<=n&&y>=1&&y<=m)return 1;
    return 0;
}
void bfs()
{
    memset(vis,0,sizeof(vis));
    while(!q.empty())q.pop();
    int x,y,t;
    q.push((ss){x1,y1,0});
    while(!q.empty())
    {
        x=q.front().x;
        y=q.front().y;
        t=q.front().t;
      //  printf(" %d %d %d\n",x,y,t);
        if(x==x2&&y==y2){
            ans=t;
            return ;
        }
        //if(t>500)return;
        q.pop();
        int xx,yy;
        getdogsight(t);
        for(int i=0;i<4;i++)
        {
            xx=x+dx[i];
            yy=y+dy[i];
            if(judside(xx,yy)&&!vis[xx][yy]&&mapp[xx][yy]!='*'&&!dogsight[xx][yy])
            {
                vis[xx][yy]=1;
                q.push((ss){xx,yy,t+1});
            }
        }
        if(!dogsight[x][y])q.push((ss){x,y,t+1});


    }

}

// 方向上左下右 0 1 2 3
int getdir(int f,int ind)
{
    if(ind==0)return (f+1)%4;
    else return (f+3)%4;
}
void getdogpath()
{
    dog[0].x=x3;
    dog[0].y=y3;
    dog[0].t=0;//for(int i=0;i<1;i++)printf("%d %d %d %d\n",i,dog[i].x,dog[i].y,dog[i].t);
    for(int i=0;i<d;i++)
    {
        if(act[i]=='G'){
            if(mapp[dog[i].x+dx[dog[i].t]][dog[i].y+dy[dog[i].t]]=='*'){
                dog[i+1].x=dog[i].x;
                dog[i+1].y=dog[i].y;
                dog[i+1].t=dog[i].t;
            }
            dog[i+1].x=dog[i].x+dx[dog[i].t];
            dog[i+1].y=dog[i].y+dy[dog[i].t];
            dog[i+1].t=dog[i].t;
        }
        else if(act[i]=='R'){
            dog[i+1].x=dog[i].x;
            dog[i+1].y=dog[i].y;
            dog[i+1].t=getdir(dog[i].t,0);

        }
        else {
            dog[i+1].x=dog[i].x;
            dog[i+1].y=dog[i].y;
            dog[i].t=getdir(dog[i].t,1);
        }
    }
    for(int i=0;i<d;i++)dog[i]=dog[i+1];//狗走完一个循环的最后一步,回到原位不花时间
   // for(int i=1;i<=d;i++)printf("%d %d %d %d\n",i,dog[i].x,dog[i].y,dog[i].t);
}
int main()
{
    int k=1;
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0)break;
        scanf("%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&d);
        scanf("%s",act);
        for(int i=1;i<=n;i++){
                scanf("%s",mapp[i]);
                for(int j=m;j>=1;j--)mapp[i][j]=mapp[i][j-1];
        }
        getdogpath();
        /*
        for(int t=1;t<=10;t++)
        {
            printf(" t= %d \n",t);
            getdogsight(t);
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    printf("%d",dogsight[i][j]);
                }
                printf("\n");
            }
        }
        */
        ans=-1;
        bfs();
        if(k>1)printf("\n");
        printf("Case %d:\n",k++);
        if(ans!=-1)printf("Minimal time is: %d\n",ans);
        else printf("No way out\n");


    }
    return 0;
}

AC代码:

#include<iostream>
#include<string>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
string maze[51];
char action[51];
int m,n,k,t,D,X1,X2,X3,Y1,Y2,Y3,flag,mark[51][51][51];
typedef struct
{
    int x,y;
    int step;
}Mov;
int patrol[51][3];//fatdog巡逻路线表:[0],[1]表示位置,[2]表示方向
int act[5][2]={{0,0},{-1,0},{1,0},{0,-1},{0,1}};
bool judge(Mov t)
{
    int i;
    if(patrol[k][0]==t.x)//狗和人在同一行
    {
        if(patrol[k][1]>t.y)//狗在人右边
        {
            if(patrol[k][2]==3)//狗朝左
            {
                for(i=t.y+1;i<patrol[k][1];i++)//检测人和狗之间有无墙
                {
                    if(maze[t.x][i]=='*')
                        return 1;
                }
                return 0;
            }
            else
            {
                return 1;
            }
        }
        else if(patrol[k][1]<t.y)
        {
            if(patrol[k][2]==4)
            {
                for(i=patrol[k][1]+1;i<t.y;i++)
                {
                    if(maze[t.x][i]=='*')
                        return 1;
                }
                return 0;
            }
            else
            {
                return 1;
            }
        }
    }
    else if(patrol[k][1]==t.y)//狗和人在同一列
    {
        if(patrol[k][0]>t.x)//狗在人上面
        {
            if(patrol[k][2]==1)
            {
                for(i=t.x+1;i<patrol[k][0];i++)
                {
                    if(maze[i][t.y]=='*')
                        return 1;
                }
                return 0;
            }
            else
            {
                return 1;
            }
        }
        else if(patrol[k][0]<t.x)
        {
            if(patrol[k][2]==2)
            {
                for(i=patrol[k][0]+1;i<t.x;i++)
                {
                    if(maze[i][t.y]=='*')
                        return 1;
                }
                return 0;
            }
            else
            {
                return 1;
            }
        }
    }
    return 1;
}
bool check(Mov t)
{
    if(t.step%D==0)
        k=D;
    else
        k=t.step%D;
    if(mark[t.x][t.y][k]==0&&(!(patrol[k][0]==t.x&&patrol[k][1]==t.y))/*不走到狗身上*/)
        return 1;
    else
        return 0;
}
void bfs()
{
    if(X1==X2&&Y1==Y2)
    {
        flag=1;
        cout<<"Minimal time is: "<<0<<endl;
        return ;
    }
    queue<Mov> q;
    Mov f,c,temp;
    int i;
    f.step=0;
    f.x=X1;
    f.y=Y1;
    mark[f.x][f.y][f.step%(D+1)]=1;
    q.push(f);
    while(!q.empty())
    {
        c=q.front();
        q.pop();

        for(i=0;i<5;i++)
        {
            temp.step=c.step+1;
            temp.x=c.x+act[i][0];
            temp.y=c.y+act[i][1];
            if(
                (temp.x>=0&&temp.x<m&&temp.y>=0&&temp.y<n)/*在迷宫内部*/
                &&(maze[temp.x][temp.y]!='*')/*墙不能走*/
                &&(check(temp))
                &&(judge(temp))/*不能在狗的视线之内)*/
                )
            {
                if(temp.x==X2&&temp.y==Y2)
                {
                    flag=1;
                    cout<<"Minimal time is: "<<temp.step<<endl;
                    return ;
                }

                mark[temp.x][temp.y][k]=1;
                q.push(temp);
            }
        }
    }
}
int main()
{
    int i,ca;
    ca=1;
    while(scanf("%d %d",&m,&n))
    {
        if(m==0&&n==0)
            break;
        scanf("%d%d%d%d%d%d%d",&X1,&Y1,&X2,&Y2,&X3,&Y3,&D);
        X1--;Y1--;X2--;Y2--;X3--;Y3--;//0,1对应
        patrol[0][0]=X3;
        patrol[0][1]=Y3;
        patrol[0][2]=1;
        for(i=1;i<=D;i++)
        {
            cin>>action[i];
            if(action[i]=='G')
            {
                if(patrol[i-1][2]==1)//N
                {
                    patrol[i][0]=patrol[i-1][0]-1;
                    patrol[i][1]=patrol[i-1][1];
                    patrol[i][2]=1;
                }
                else if(patrol[i-1][2]==2)//S
                {
                    patrol[i][0]=patrol[i-1][0]+1;
                    patrol[i][1]=patrol[i-1][1];
                    patrol[i][2]=2;
                }
                else if(patrol[i-1][2]==3)//W
                {
                    patrol[i][0]=patrol[i-1][0];
                    patrol[i][1]=patrol[i-1][1]-1;
                    patrol[i][2]=3;
                }
                else if(patrol[i-1][2]==4)//E
                {
                    patrol[i][0]=patrol[i-1][0];
                    patrol[i][1]=patrol[i-1][1]+1;
                    patrol[i][2]=4;
                }
            }
            else if(action[i]=='L')
            {
                patrol[i][0]=patrol[i-1][0];
                patrol[i][1]=patrol[i-1][1];
                if(patrol[i-1][2]==1)
                {
                    patrol[i][2]=3;
                }
                else if(patrol[i-1][2]==2)
                {
                    patrol[i][2]=4;
                }
                else if(patrol[i-1][2]==3)
                {
                    patrol[i][2]=2;
                }
                else if(patrol[i-1][2]==4)
                {
                    patrol[i][2]=1;
                }
            }
            else if(action[i]=='R')
            {
                patrol[i][0]=patrol[i-1][0];
                patrol[i][1]=patrol[i-1][1];
                if(patrol[i-1][2]==1)
                {
                    patrol[i][2]=4;
                }
                else if(patrol[i-1][2]==2)
                {
                    patrol[i][2]=3;
                }
                else if(patrol[i-1][2]==3)
                {
                    patrol[i][2]=1;
                }
                else if(patrol[i-1][2]==4)
                {
                    patrol[i][2]=2;
                }
            }
        }
        for(i=0;i<m;i++)
        {
            cin>>maze[i];
        }//end of input

        memset(mark,0,sizeof(mark));
        if(ca!=1)
            cout<<endl;
        cout<<"Case "<<ca++<<":"<<endl;
        flag=0;
        bfs();
        if(flag==0)
            cout<<"No way out"<<endl;
    }
    return 0;
}


pat1043

#include <iostream>
using namespace std;

int flag;   //是否符合条件标志位,0符合,1不符合

struct node //树中的点
{
    int value;  //值
    node *left,*right; //左右子树
};

node* Build1(int *data,int p,int q) //数据,起始、终止位置[p,q];
{
    if(p>q)
        return NULL;
    if(flag==1) //不符合条件,直接跳出(应该放到最前)
        return NULL;

    node* root=new node;
    root->value=data[p];

    if(p==q)    //只有一个数
    {
        root->left=NULL;
        root->right=NULL;
        return root;
    }
    int i;
    int r=p;    //第一个比data[p]大的数
    for(i=p+1;i<=q;i++)
    {
        if(data[i]>=data[p])
        {
            r=i;
            break;
        }
    }
    if(r>p)  //找得到比data[p]大的data[r]
    {
        for(i=r+1;i<=q;i++)
        {
            if(data[i]<data[p])
            {
                flag=1;
                return NULL;
            }
        }
        root->left=Build1(data,p+1,r-1);
        root->right=Build1(data,r,q);
    }
    else    //找不到
    {
        root->left=Build1(data,p+1,q);
        root->right=NULL;
    }
    return root;
}

node* Build2(int *data,int p,int q) //镜像
{
    if(p>q)
        return NULL;
    if(flag==1)
        return NULL;

    node* root=new node;
    root->value=data[p];

    if(p==q)
    {
        root->left=NULL;
        root->right=NULL;
        return root;
    }
    int i;
    int r=p;
    for(i=p+1;i<=q;i++)
    {
        if(data[i]<data[p])  //注意镜像的定义
        {
            r=i;
            break;
        }
    }
    if(r>p)
    {
        for(i=r+1;i<=q;i++)
        {
            if(data[i]>=data[p])
            {
                flag=1;
                return NULL;
            }
        }
        root->left=Build2(data,p+1,r-1);
        root->right=Build2(data,r,q);
    }
    else
    {
        root->left=Build2(data,p+1,q);
        root->right=NULL;
    }
    return root;
}

int put_flag=0; //是否输出过信息标志位,用于跳过第一个空格

void Put_data(node *root)
{
    if(root->left!=NULL)
        Put_data(root->left);
    if(root->right!=NULL)
        Put_data(root->right);
    if(put_flag==1)
        cout<<" ";
    else
        put_flag=1;
    cout<<root->value;
}

int main()
{
    int n,data[1001];   //数据
    int i;
    cin>>n;
    for(i=0;i<n;i++)
        cin>>data[i];
    if(n==1)    //只有一个值,符合条件
    {
        cout<<"YES\n";
        cout<<data[0];
        return 0;
    }
    flag=0; //考虑正向
    node *root=Build1(data,0,n-1);
    if(flag==0)
    {
        cout<<"YES\n";
        Put_data(root);
        return 0;
    }
    flag=0; //考虑镜像
    root=Build2(data,0,n-1);
    if(flag==0)
    {
        cout<<"YES\n";
        Put_data(root);
    }
    else    //都不符合
        cout<<"NO";
    return 0;
}


这个题目是考察二查搜索树,但其实实际上并不需要我们建立一个二叉树,我们只需要在重构的过程中,利用递归的思想直接进行一次遍历即可。

本代码中使用到了lambda表达式,所以代码量比较简洁,只有40行,c++里面还真有很多有趣的特性。

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
 
int N;
int A[1005];
vector<int> res;//存放输出结果
int value;//临时变量,用于lambda函数内部
function<int (int)> func = [=](int i){return i>=value;}; //lambda函数指针
void tree(int* a, int* b){
    if(a>=b)
        return; //递归出口
    value = *a;
    int* center = find_if(a+1,b,func);  //数组分成3部分,分别是:根元素 左子树 右子树 
    if(!all_of(center,b,func)) //测试右子树是否满足条件
        return;
    tree(a+1,center);    //遍历左子树
    tree(center,b);      //遍历右子树
    res.push_back(*a);   //存储输出
}
int main(){
    scanf("%d",&N);
    for(int i=0;i<N;i++){
        scanf("%d",A+i);
    }
    if(N>1 && A[0]<=A[1])
        func = ([=](int i){return i<value;});//如果是mirror,改变lambda函数
    tree(A,A+N);
    if(res.size()!=N)
        printf("NO\n");
    else{//输出
        printf("YES\n");
        printf("%d",res[0]);
        for(int i=1;i<res.size();i++)
            printf(" %d",res[i]);
    }
    return 0;
}

ZOJ1944 已知前序和中序求后序

不建树版

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char pre[30],in[30];
int num;
void Postorder(int l,int r)
{

    if(l>r)return ;
    if(l==r){
        num++;
        printf("%c",in[l]);
        return;
    }
    int re=l;
    for(int i=l;i<=r;i++)
    {
        if(in[i]==pre[num]){
            re=i;
            break;
        }
    }
    num++;
    Postorder(l,re-1);
    Postorder(re+1,r);
    printf("%c",in[re]);

}

int main()
{
    int n;
    while(~scanf("%s%s",pre,in))
    {
       num=0;
       Postorder(0,strlen(pre)-1);
       printf("\n");
    }
    return 0;
}

建树版

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char pre[30],in[30];
struct node
{
    char value;
    node *left,*right;
};
int num;
node* Build(int l,int r)
{
   // printf("%d %d %d\n",num,l,r);
    node* root=new node;
    root->value=pre[num];
    if(l>r)return NULL;
    if(l==r){
        num++;
        root->left=NULL;
        root->right=NULL;
        return root;
    }

    int i;
    int re=l;
    for(i=l;i<=r;i++)
    {
        if(in[i]==pre[num]){
            re=i;
            break;
        }
    }
    num++;
    root->left=Build(l,re-1);
    root->right=Build(re+1,r);
    return root;
}
void Put_data(node *root)
{
    if(root->left!=NULL)Put_data(root->left);
    if(root->right!=NULL)Put_data(root->right);
    printf("%c",root->value);
}
int main()
{
    int n;
    while(~scanf("%s%s",pre,in))
    {
        num=0;
        node* root=Build(0,strlen(in)-1);

        Put_data(root);
        printf("\n");
    }
    return 0;
}


pat1086 先序建树,后序输出,简单题

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct Node{
    int value;
    Node *leftChild;
    Node *rightChild;
    Node(int v):value(v),leftChild(NULL),rightChild(NULL){}
};
char ch[10];
int n,num;
int flag;
Node* Build(Node* root)
{
    if(num>=2*n)return NULL;
    scanf("%s",ch);
    if(ch[1]=='u'){
        root=new Node(0);
        scanf("%d",&root->value);
        num++;
        root->leftChild=Build(root->leftChild);
        root->rightChild=Build(root->rightChild);
    }
    else {
            root=NULL;
            num++;
    }
    return root;
}
void PutTree(Node *root)
{
    if(root!=NULL){
        PutTree(root->leftChild);
        PutTree(root->rightChild);
        if(!flag){
            printf("%d",root->value);
            flag=1;
        }
        else printf(" %d",root->value);
    }
}
int main()
{
    while(~scanf("%d",&n))
    {
        Node *root=NULL;
        num=0;
        flag=0;
        root=Build(root);
        PutTree(root);
        puts("");
    }
    return 0;
}



POJ 3667 区间合并

http://www.cnblogs.com/kedebug/archive/2013/01/20/2868210.html

题意:

有N个房间,M次操作。1 a表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示入住。2 b len把起点为b长度的len的房

线段树的区间合并和查询:

1. sum[]表示区间内最大的连续房间数

2. lsum[], rsum[]分别表示区间从左边、右边起的连续房间数目

3. 主要是其中的更新过程比较繁琐,理清楚逻辑就不是那么难了

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

#define lhs l, m, rt << 1
#define rhs m + 1, r, rt << 1 | 1

const int maxn = 50010;
int sum[maxn << 2], lab[maxn << 2];
int lsum[maxn << 2], rsum[maxn << 2];

enum __check { checkout = 0, checkin };

void PushDown(int rt, int m)
{
    if (lab[rt] != -1)
    {
        lab[rt << 1] = lab[rt << 1 | 1] = lab[rt];
        sum[rt << 1] = lsum[rt << 1] = rsum[rt << 1] = lab[rt] ? 0 : m - (m >> 1);
        sum[rt << 1 | 1] = lsum[rt << 1 | 1] = rsum[rt << 1 | 1] = lab[rt] ? 0 : (m >> 1);
        lab[rt] = -1;
    }
}

void PushUp(int rt, int m)
{
    lsum[rt] = lsum[rt << 1];
    rsum[rt] = rsum[rt << 1 | 1];

    if (lsum[rt] == m - (m >> 1))
        lsum[rt] += lsum[rt << 1 | 1];
    if (rsum[rt] == m >> 1)
        rsum[rt] += rsum[rt << 1];

    sum[rt] = max(rsum[rt << 1] + lsum[rt << 1 | 1], max(sum[rt << 1], sum[rt << 1 | 1]));
}

void Build(int l, int r, int rt)
{
    sum[rt] = lsum[rt] = rsum[rt] = r - l + 1;
    lab[rt] = -1;
    if (l == r)
        return ;
    int m = (l + r) >> 1;
    Build(lhs);
    Build(rhs);
}

void Update(int beg, int end, __check c, int l, int r, int rt)
{
    if (beg <= l && r <= end)
    {
        sum[rt] = lsum[rt] = rsum[rt] = c ? 0 : r - l + 1;
        lab[rt] = c;
        return ;
    }
    PushDown(rt, r - l + 1);

    int m = (l + r) >> 1;
    if (beg <= m)
        Update(beg, end, c, lhs);
    if (end > m)
        Update(beg, end, c, rhs);

    PushUp(rt, r - l + 1);
}

int Query(int w, int l, int r, int rt)
{
    if (l == r)
        return r;

    PushDown(rt, r - l + 1);

    int m = (l + r) >> 1;
    if (sum[rt << 1] >= w)
        return Query(w, lhs);
    else if (rsum[rt << 1] + lsum[rt << 1 | 1] >= w)
        return m - rsum[rt << 1] + 1;
    else
        return Query(w, rhs);
}

int main()
{
    int n, m;
    scanf("%d %d", &n, &m);

    Build(1, n, 1);

    for (int i = 0; i < m; ++i)
    {
        int op, a, b;
        scanf("%d", &op);

        if (op == 1)
        {
            scanf("%d", &a);
            if (sum[1] >= a)
            {
                int p = Query(a, 1, n, 1);
                printf("%d\n", p);
                Update(p, p + a - 1, checkin, 1, n, 1);
            }
            else
                printf("0\n");
        }
        else if (op == 2)
        {
            scanf("%d %d", &a, &b);
            Update(a, a + b - 1, checkout, 1, n, 1);
        }
    }
    return 0;
}



pat 1066 平衡二叉树的旋转插入

http://blog.youkuaiyun.com/tiantangrenjian/article/details/12891091

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct Node
{
    int value;
    int height;
    Node *leftChild;
    Node *rightChild;
    Node(int v):value(v),leftChild(NULL),rightChild(NULL),height(0){}
};
int getHeight(Node *node)
{
    if(node == NULL)return -1;
    return node->height;
}
bool isBalance(Node* parent)
{
    return abs(getHeight(parent->leftChild)-getHeight(parent->rightChild))<2;
}
Node* rotate_LL(Node* parent)
{
    Node* child=parent->leftChild;
    parent->leftChild=child->rightChild;
    child->rightChild=parent;

    parent->height = max(getHeight(parent->leftChild),getHeight(parent->rightChild))+1;
    child->height = max(getHeight(child->leftChild),getHeight(child->rightChild))+1;
    return child;
}
Node* rotate_RR(Node* parent)
{
    Node* child=parent->rightChild;
    parent->rightChild=child->leftChild;
    child->leftChild=parent;

    parent->height = max(getHeight(parent->leftChild),getHeight(parent->rightChild))+1;
    child->height = max(getHeight(child->leftChild),getHeight(child->rightChild))+1;
    return child;
}
Node* rotate_LR(Node* parent)
{
    Node* child=parent->leftChild;
    parent->leftChild=rotate_RR(child);
    return rotate_LL(parent);
}
Node* rotate_RL(Node *parent)
{
    Node* child=parent->rightChild;
    parent->rightChild=rotate_LL(child);
    return rotate_RR(parent);
}
Node* InsertNode(Node* root,int newValue)
{
    if(root!=NULL)
    {
        if(newValue>root->value)
        {
            root->rightChild=InsertNode(root->rightChild,newValue);
            if(!isBalance(root))
            {
                if(newValue>root->rightChild->value)
                {
                    root=rotate_RR(root);
                }
                else root=rotate_RL(root);
            }
        }
        else
        {
            root->leftChild=InsertNode(root->leftChild,newValue);
            if(!isBalance(root))
            {
                if(newValue>root->leftChild->value)
                    root=rotate_LR(root);
                else root=rotate_LL(root);
            }
        }

    }
    else{
        root=new Node(newValue);
    }
    root->height=max(getHeight(root->leftChild),getHeight(root->rightChild))+1;
    return root;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int val;
        Node *root=NULL;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&val);
            root=InsertNode(root,val);
        }
        printf("%d\n",root->value);
    }
    return 0;
}



///

1044 16/25

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 100010
#define inf 0x7fffffff
int main()
{
    int n,m,x;
    int s[N];
    while(~scanf("%d%d",&n,&m))
    {
        s[0]=0;
        for(int i=1;i<=n;i++){
                scanf("%d",&x);
                s[i]=s[i-1]+x;
            //   printf("** %d %d\n",i,s[i]);
        }
        int flag=0;
        int mi=inf,a,b;
        for(int i=0;i<=n;i++)
        {
            int p=lower_bound(s+i,s+n+1,s[i]+m)-s;
          //  printf("--- %d %d\n",i,p);
            if(s[p]==s[i]+m){
                    printf("%d-%d\n",i+1,p);
                    flag=1;
            }
            else if(s[p]-s[i]>m&&s[p]-s[i]<inf)
            {
                a=i+1;
                b=p;
            }
        }
        if(flag==0)
        {
            printf("%d-%d\n",a,b);
        }

    }
    return 0;
}
/*
5 16
2 4 5 7 9

*/



pat1057 树状数组求中位数

#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
#define lowbit(x) x&(-x)
#define N 100010
int c[N];
void add(int i,int val)
{
    while(i<N)
    {
        c[i]+=val;
        i+=lowbit(i);
    }
}
int getsum(int i)
{
    int sum=0;
    while(i>0)
    {
        sum+=c[i];
        i-=lowbit(i);
    }
    return sum;
}
int binsearch()
{
    int l=1,r=100000;
    int k=getsum(100000);
    k=(k+1)/2;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(getsum(mid)>=k)r=mid;
        else l=mid+1;
    }
    return r;
}

int main()
{
    char op[20];
    int n;
    stack<int>q;
    while(~scanf("%d",&n))
    {
        memset(c,0,sizeof(c));
        while(!q.empty())q.pop();
        while(n--)
        {
            scanf("%s",op);
            if(strcmp(op,"Pop")==0)
            {
                if(q.empty())
                {
                    printf("Invalid\n");
                }
                else {
                    printf("%d\n",q.top());
                    add(q.top(),-1);
                    q.pop();
                }
            }
            else if(strcmp(op,"PeekMedian")==0)
            {
                if(q.empty()){
                    printf("Invalid\n");
                }
                else
                {
                    printf("%d\n",binsearch());
                }
            }
            else
            {
                int x;
                scanf("%d",&x);
                q.push(x);
                add(x,1);
            }
            //for(int i=0;i<10;i++)printf("  ** %d %d\n",i,getsum(i));
        }
    }

    return 0;
}

pat1059求一个数的所有素数因子

#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
int main()
{
    long long n,i;
    while(~scanf("%lld",&n))
    {
        i=2;
        int flag=1;
        printf("%lld=",n);
        if(n==1)printf("1");
        while(1)
        {
            if(n%i==0)
            {
                n/=i;
                if(flag){
                        printf("%lld",i);
                        flag=0;
                }
                else printf("*%lld",i);
                int k=1;
                while(n%i==0)
                {
                    n/=i;
                    k++;
                }
                if(k>1)printf("^%d",k);
            }
            else i++;
            if(i*i>n)
            {
                if(n!=1){
                    if(flag){
                            printf("%lld",n);
                            flag=0;
                    }
                    else printf("*%lld",n);
                }
                puts("");
                break;
            }
        }
    }
    return 0;
}


pat 1082  1y 细节题 知道什么后面一定只能是什么判断一下即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
using namespace std;
char num[20][10]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
char jin[10][10]={"Wan","Shi","Bai","Qian","Yi"};
int s[20];
int getwei(int n)
{
    int sum=0;
    int ss[20];
    int k=0;
    while(n)
    {
        ss[k++]=n%10;
        n/=10;
        sum++;
    }
    for(int i=0;i<k;i++)s[i]=ss[k-i-1];
    return sum;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int first=1;
        if(n==0){
            puts("ling");
            continue;
        }
        if(n<0){
                if(!first)printf(" ");
                first=0;
                printf("Fu");
                n=-n;
        }
        int k=getwei(n);
        if(k==1)
        {
            if(!first)printf(" ");
            first=0;
            puts(num[n]);
            continue;
        }
        int pre=1,p0=0;
        // 1: yi er san..
        // 0: ling
        // 2: Shi Bai Qian Wang
        // 3: Yi
        for(int i=0;i<k;i++)
        {
           // printf("i= %d pre= %d \n",i,pre);

            if(s[i]!=0)
            {
                if(!first)printf(" ");
                first=0;
                printf("%s",num[s[i]]);
                pre=1;
            }
            else
            {
                if(pre>=2&&i==p0){
                        if(!first)printf(" ");
                        first=0;
                        printf("%s",num[0]);
                        pre=0;
                }
            }
            if(i==k-1)break;
            int p=k-i-1;
            if(pre!=0){
                if(p%8==0){
                        if(!first)printf(" ");
                        first=0;
                        printf("%s",jin[4]);
                        pre=3;
                }
                else {
                        if(pre==1||(pre==2&&p%4==0)){
                            if(!first)printf(" ");
                            first=0;
                            printf("%s",jin[p%4]);
                            pre=2;
                        }
                }
            }
            int j;
            for(j=i+1;j<k;j++){
                    if(s[j]!=0){
                            p0=j-1;
                            break;
                    }
            }
            if(j>=k)break;
        }
        puts("");
    }
    return 0;
}
/*
-1000003
-10000003
*/


pat1078 哈希表二次探测

http://www.cnblogs.com/foreverking/articles/2339735.html

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
using namespace std;
#define N 10010
int a[N],vis[N];
bool jud(int n)
{
    if(n==1)return false;
    for(int i=2;i<=sqrt(n);i++)
        if(n%i==0)return false;
    return true;
}
int main()
{
    int m,n,i,j;
    while(~scanf("%d%d",&m,&n))
    {
        memset(vis,0,sizeof(vis));
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        while(!jud(m))m++;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                int k=(a[i]+j*j)%m;
                if(!vis[k])
                {
                    vis[k]=1;
                    if(i==n-1)printf("%d\n",k);
                    else printf("%d ",k);
                    break;
                }
            }
            if(j>=m){
                    if(i==n-1)printf("-\n");
                    else printf("- ");
            }
        }
    }
    return 0;
}

pat1049数学,找规律

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int f=1;
        int ans=0;
        int high,low,now;
        while(n/f!=0)
        {
            //printf("f = %d\n",f);
            high=n/(f*10);
            low=n-(n/f)*f;
            now=(n/f)%10;
            if(now==0)ans+=high*f;
            else if(now==1)ans+=high*f+low+1;
            else ans+=high*f+f;
            f*=10;
        }
        printf("%d\n",ans);
    }
    return 0;
}


pat1087

http://www.aichengxu.com/view/34533

做完后感觉我对Dijkstra算法的掌握程度有所提升了

#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
using namespace std;
#define INF 2100000000
#define MAX 300
map<string,int>nameNum;
map<int,string>numName;
int n,m;
bool visited[MAX];
int cost[MAX][MAX];
int pre[MAX];
int dis[MAX];
int happyvalue[MAX];
int final_happyness[MAX];
int pre_city_cnt[MAX];
int road_cnt[MAX];
void inti()
{
    char name1[5],name2[5];
    scanf("%d%d%s",&n,&m,name1);
    nameNum[name1]=0;
    numName[0]=name1;
    memset(visited,false,sizeof(visited));
    memset(final_happyness,0,sizeof(final_happyness));
    memset(pre_city_cnt,0,sizeof(pre_city_cnt));
    memset(road_cnt,0,sizeof(road_cnt));
    for(int i=0;i<n;i++)
    {
        dis[i]=INF;
        for(int j=0;j<n;j++)cost[i][j]=INF;
    }
    for(int i=1;i<n;i++)
    {
        scanf("%s%d",name1,&happyvalue[i]);
        nameNum[name1]=i;
        numName[i]=name1;
    }
    int dist;
    for(int i=0;i<m;i++)
    {
        scanf("%s%s%d",name1,name2,&dist);
        cost[nameNum[name1]][nameNum[name2]]=cost[nameNum[name2]][nameNum[name1]]=dist;
    }
}
void Dijkstra()
{
    dis[0]=0;
    road_cnt[0]=1;//入口值,一条入口路径

    for(int k=0;k<n;k++)
    {
        int index=-1;
        int mindis=INF;
        for(int i=0;i<n;i++)
        {
            if(visited[i]==false&&dis[i]<mindis)
            {
                index=i;
                mindis=dis[i];
            }
        }
       // printf("** %d %d\n",index,mindis);
        if(index==-1)
        {
            break;
        }
        visited[index]=true;
        for(int i=0;i<n;i++)
        {
            if(dis[i]>dis[index]+cost[index][i])
            {
                road_cnt[i]=road_cnt[index];

                dis[i]=dis[index]+cost[index][i];
                final_happyness[i]=final_happyness[index]+happyvalue[i];
                pre_city_cnt[i]=pre_city_cnt[index]+1;
                pre[i]=index;
            }
            else if(dis[i]==dis[index]+cost[index][i])
            {
                road_cnt[i]+=road_cnt[index];

                if(final_happyness[i]<final_happyness[index]+happyvalue[i])
                {
                    final_happyness[i]=final_happyness[index]+happyvalue[i];
                    pre_city_cnt[i]=pre_city_cnt[index]+1;
                    pre[i]=index;
                }
                else if(final_happyness[i]==final_happyness[index]+happyvalue[i])
                {
                    if(pre_city_cnt[i]>pre_city_cnt[index]+1)
                    {
                        pre_city_cnt[i]=pre_city_cnt[index]+1;
                        pre[i]=index;
                    }
                }
            }

        }
    }
}
void print(int city)
{
    if(city==0)
    {
        int dest=nameNum[(string)"ROM"];
        printf("%d %d %d %d\n",road_cnt[dest],dis[dest],final_happyness[dest],final_happyness[dest]/ pre_city_cnt[dest]);
        printf("%s",numName[0].c_str());
    }
    else{
        print(pre[city]);
        printf("->%s",numName[city].c_str());
    }
}
int main()
{
    inti();
    Dijkstra();
    print(nameNum[(string)"ROM"]);
   // puts("");
    return 0;
}

pat1030 做法同1087 ,更懂了

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 550
#define INF 2100000000
int cost[maxn][maxn];
int price[maxn][maxn];
int dis[maxn];
int pri[maxn];
bool vis[maxn];
int pre[maxn];
int cityNum,roadNum,root,scourse;
void inti()
{
    scanf("%d%d%d%d",&cityNum,&roadNum,&root,&scourse);
    for(int i=0;i<cityNum;i++)
    {
        dis[i]=INF;
        pri[i]=INF;
        for(int j=0;j<cityNum;j++)
        {
            cost[i][j]=INF;
            price[i][j]=INF;
        }
    }
    int st,en,cos,ppri;
    while(roadNum--)
    {
        scanf("%d%d%d%d",&st,&en,&cos,&ppri);
        cost[st][en]=cost[en][st]=cos;
        price[st][en]=price[en][st]=ppri;

    }
    memset(vis,false,sizeof(vis));
    memset(pre,-1,sizeof(pre));
    memset(pri,0,sizeof(pri));


}

void Dijkstra()
{
    dis[root]=0;
    for(int k=0;k<cityNum;k++)
    {
        int mindis=INF;
        int index=-1;
        for(int i=0;i<cityNum;i++)
        {
            if(!vis[i]&&dis[i]<mindis)
            {
                mindis=dis[i];
                index=i;
            }
        }
        if(index==-1)
        {
            break;
        }
       // printf("index=%d %d\n",index,mindis);
        vis[index]=1;
        for(int i=0;i<cityNum;i++)
        {
            if(dis[i]>dis[index]+cost[index][i])
            {
                dis[i]=dis[index]+cost[index][i];
                pri[i]=pri[index]+price[index][i];
                pre[i]=index;
             //   printf("i=%d index=%d %d\n",i,index,dis[i]);
            }
            else if(dis[i]==dis[index]+cost[index][i])
            {
                if(pri[i]>pri[index]+price[index][i])
                {
                    pri[i]=pri[index]+price[index][i];
                    pre[i]=index;
                }
            }

        }

    }
}
void Output(int city)
{

    if(city==root){
        printf("%d",city);
        return;
    }
    else{
        Output(pre[city]);
        printf(" %d",city);
    }
}
int main()
{
    inti();
    Dijkstra();
    Output(scourse);
    printf(" %d %d\n",dis[scourse],pri[scourse]);

    return 0;
}



pat1080 简单的结构体排序,就是喜欢上课这种编程风格,分inti(),work(),output() 模块,并且英语单词来表意,而不是a,b,c,d这样的符号

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
#define maxn 40004
#define maxm 105
int stuNum,schNum,perNum;
int lastRank[maxn];
int schQuota[maxn];
vector<int>school[maxm];
struct student
{
    int stuId;
    int GE,GI;
    int finGrade;
    int perSchool[10];
    int rankNum;
}stu[maxn];
bool cmp(student s1,student s2)
{
    if(s1.finGrade==s2.finGrade)
    {
        return s1.GE>s2.GE;
    }
    return s1.finGrade>s2.finGrade;
}
bool isEqual(student s1,student s2)
{
    if(s1.finGrade==s2.finGrade&&s1.GE==s2.GE)return true;
    return false;
}
void inti()
{
    scanf("%d%d%d",&stuNum,&schNum,&perNum);
    for(int i=0;i<schNum;i++)scanf("%d",&schQuota[i]);
    for(int i=0;i<stuNum;i++)
    {
        scanf("%d%d",&stu[i].GE,&stu[i].GI);
        stu[i].finGrade=stu[i].GE+stu[i].GI;
        for(int j=0;j<perNum;j++)scanf("%d",&stu[i].perSchool[j]);
        stu[i].stuId=i;
    }
    sort(stu,stu+stuNum,cmp);

    stu[0].rankNum=0;
    for(int i=1;i<stuNum;i++)
    {
        if(isEqual(stu[i],stu[i-1]))stu[i].rankNum=stu[i-1].rankNum;
        else stu[i].rankNum=i;
    }
    for(int i=0;i<schNum;i++)school[i].clear();
    memset(lastRank,-1,sizeof(lastRank));
}
void select()
{
    for(int i=0;i<stuNum;i++)
    {
        for(int j=0;j<perNum;j++)
        {
          //  if(stu[i].stuId==5)printf("j=%d\n",stu[i].perSchool[j]);
            int sId=stu[i].perSchool[j];
            if(school[sId].size()<schQuota[sId])
            {
                school[sId].push_back(stu[i].stuId);
                lastRank[sId]=stu[i].rankNum;
                break;
            }
            else if(school[sId].size()>0&&stu[i].rankNum==lastRank[sId])
            {
                school[sId].push_back(stu[i].stuId);
                break;
            }
        }
    }
}
void output()
{
    for(int i=0;i<schNum;i++)
    {
        if(school[i].size()==0)puts("");
        else{
            sort(school[i].begin(),school[i].end());
            printf("%d",school[i][0]);
            for(int j=1;j<school[i].size();j++)
            {
                printf(" %d",school[i][j]);
            }
            puts("");
        }
    }
}
int main()
{
    inti();
    select();
    output();
    return 0;
}


pat1076DFS+剪枝

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 1010
vector<int>user[maxn];
int userNum,maxLevel;
bool visited[maxn];
bool opened[maxn];
void inti()
{
    scanf("%d%d",&userNum,&maxLevel);
    for(int i=1;i<=userNum;i++)user[i].clear();
    for(int i=1;i<=userNum;i++)
    {
        int num,to;
        scanf("%d",&num);
        while(num--)
        {
            scanf("%d",&to);
            user[to].push_back(i);
        }
    }
/*
    for(int i=1;i<=userNum;i++)
    {
        printf("i=%d \\",i);
        for(int j=0;j<user[i].size();j++)
        {
            printf("%d ",user[i][j]);
        }
        puts("");
    }
*/

}
void DFS(int root,int level)
{
  //  printf("%d %d %d\n",root,visited[root],level);
    if(visited[root]&&opened[root])return;
    //剪枝 opened表示root下的关注列表已经被展开过
    visited[root]=true;
    if(user[root].size()==0)
    {
        opened[root]=true;
        return;
    }
    if(level<maxLevel){
        opened[root]=true;
        for(int i=0;i<user[root].size();i++)
        {
            DFS(user[root][i],level+1);
        }
    }
}
void work()
{
    int Q;
    scanf("%d",&Q);
    while(Q--)
    {
        int val;
        scanf("%d",&val);
        memset(visited,false,sizeof(visited));
        memset(opened,false,sizeof(opened));
        DFS(val,0);
        int sum=0;
        for(int i=1;i<=userNum;i++)
        {
            if(visited[i]){
                    sum++;
                  //  printf("i=%d\n",i);
            }
        }
        printf("%d\n",sum-1);
    }
}
int main()
{
    inti();
    work();
    return 0;
}


pat1074 最后一组数据有坑,可能有多个-1 导致链表上元素的总数不等于输入的总数

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 100010
struct Node
{
    int id;
    int address;
    int val;
    int nextNum;
}node[maxn],node2[maxn];
int firstNum,nodeNum,kNum;
int hashNum[maxn];
int totNum;
bool cmp(Node x,Node y)
{
    return x.id<y.id;
}
bool cmp2(Node x,Node y)
{
    return x.id>y.id;
}
void inti()
{
    memset(hashNum,-1,sizeof(hashNum));
    scanf("%d%d%d",&firstNum,&nodeNum,&kNum);
    for(int i=1;i<=nodeNum;i++)
    {
        int address,val,next;
        scanf("%d%d%d",&node[i].address,&node[i].val,&node[i].nextNum);
        hashNum[node[i].address]=i;
        if(node[i].nextNum==-1)hashNum[node[i].nextNum]=-1;
    };
    totNum=0;
    for(int i=hashNum[firstNum];i!=-1;i=hashNum[node[i].nextNum])
    {
      //  printf("i= %d\n",i);
        node[i].id=totNum;
        node2[totNum++]=node[i];
    }
   //
   // if(k!=nodeNum+1)while(1)k++;
    sort(node2,node2+totNum,cmp);
  //  puts("------------------");
   // for(int i=1;i<=nodeNum;i++)printf("%d  %d %d %d\n",node[i].id,node[i].address,node[i].val,node[i].nextNum);
   // puts("------------------");
}
void work()
{
    for(int i=0;i<totNum;i+=kNum)
    {
        if(i+kNum<=totNum)sort(node2+i,node2+i+kNum,cmp2);
    }
    for(int i=0;i<totNum-1;i++)node2[i].nextNum=node2[i+1].address;
    node2[totNum-1].nextNum=-1;
    for(int i=0;i<totNum;i++){
            printf("%05d %d ",node2[i].address,node2[i].val);
            if(node2[i].nextNum==-1)printf("-1\n");
            else printf("%05d\n",node2[i].nextNum);
    }

}
int main()
{
    inti();
    work();
    return 0;
}
/*
00100 8 4
00000 4 99999
00100 1 12309
68237 6 89999
33218 3 00000
99999 5 68237
12309 2 33218
89999 8 99996
99996 7 -1

00100 5 4
00000 9 99999
00100 8 12309
33218 1 00000
99999 12 -1
12309 50 33218

00000 1 1
00000 121 -1

*/


pat1047 这题告诉我 char[] 转换成string很耗时间

#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 2555
int n,m;
vector<string>stuCour[maxn];
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        while(n--)
        {
            char stuName[20];
            int courseNum,courseId;
            scanf("%s%d",stuName,&courseNum);
            string s=string(stuName);//不要写成stuCour[courseId].push_back(stuName); 否则最后一个案例超时
            while(courseNum--)
            {
                scanf("%d",&courseId);
                stuCour[courseId].push_back(s);
            }
        }
        for(int i=1;i<=m;i++)sort(stuCour[i].begin(),stuCour[i].end());
        for(int i=1;i<=m;i++)
        {
            int len=stuCour[i].size();
            printf("%d %d\n",i,len);
            for(int j=0;j<len;j++)
            {
                printf("%s\n",stuCour[i][j].c_str());
            }
        }
    }
    return 0;
}

另外一种写法 死活都是段错误,代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<string>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
#define maxn 40040
#define maxm 2555
int n,m;
vector<string>courStu[maxm];
struct ss
{
    char name[20];
    int cour[440];
    int num;
    int id;
}stu[maxn];
bool cmp(ss a, ss b)
{
    return strcmp(a.name,b.name)<0;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++)courStu[i].clear();
        for(int i=1;i<=n;i++)stu[i].num=0;
        for(int i=1;i<=n;i++)
        {
            int courseNum,courseId;
            scanf("%s%d",stu[i].name,&courseNum);
            while(courseNum--)
            {
                scanf("%d",&courseId);
                stu[i].cour[stu[i].num++]=courseId;
            }
        }
        sort(stu+1,stu+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            string s=string(stu[i].name);
            for(int j=0;j<stu[i].num;j++)
            {
                int t=stu[i].cour[j];
                courStu[t].push_back(s);
            }
        }

        for(int i=1;i<=m;i++)
        {
            printf("%d %d\n",i,courStu[i].size());
            for(int j=0;j<courStu[i].size();j++)
            {
                puts(courStu[i][j].c_str());
            }
        }
    }
    return 0;
}


pat1052 

注意点:
(1)题目中可能存在多条链表。我们只要其中一条。
(2)如果给出的起始节点的地址为-1,则输出“0 -1”。(最后一个案例错,坑就在这里!!!)

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
int hashNum[100010];
struct ss
{
    int address;
    int val;
    int next;
}a[100010],aa[100010];
bool cmp(ss x,ss y)
{
    return x.val<y.val;
}
int main()
{
    int n,firstadd;
    while(~scanf("%d%d",&n,&firstadd))
    {

        memset(hashNum,-1,sizeof(hashNum));
        hashNum[-1]=-1;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d",&a[i].address,&a[i].val,&a[i].next);
            hashNum[a[i].address]=i;
        }
        if(firstadd==-1)
        {
            printf("0 -1\n");
            continue;
        }
        int totNum=0;
        for(int i=hashNum[firstadd];i!=-1;i=hashNum[a[i].next])
        {
            aa[totNum++]=a[i];
        }
        sort(aa,aa+totNum,cmp);
        printf("%d %05d\n",totNum,aa[0].address);
        for(int i=0;i<totNum-1;i++)
        {
            printf("%05d %d %05d\n",aa[i].address,aa[i].val,aa[i+1].address);
        }
        printf("%05d %d -1\n",aa[totNum-1].address,aa[totNum-1].val);
    }
    return 0;
}
/*
1 -1
-1 32 -1

*/


pat1029 简单题

#include<iostream>
#include<cstdio>
#define N 1000010
#include<algorithm>
using namespace std;
int a[N],b[N];
int main()
{
    int n,m;
    scanf("%d",&n);
    for(int i=0;i<n;i++)scanf("%d",&a[i]);
    scanf("%d",&m);
    for(int i=0;i<m;i++)scanf("%d",&b[i]);
   // sort(a,a+n);
  //  sort(b,b+m);

    int i=0,j=0;
    int sum=0;
    while(1)
    {
        sum++;
       // printf("* %d %d\n",i,j);
        if(a[i]<b[j]&&i<n||j>=m){

            if(sum==(n+m+1)/2)
            {
                printf("%d\n",a[i]);
                break;
            }
            i++;
        }
        else {
            if(sum==(n+m+1)/2)
            {
                printf("%d\n",b[j]);
                break;
            }
            j++;
        }
    }

    return 0;
}

/*
4 1 2 3 4
5 6 7 8 9 10

5 1 2 3 4 5
4 6 7 8 9

4 1 2 3 4
1 0

*/

pat1024

题意:回文字,对输入数值进行判断,若不是回文,则反转相加继续。

分析:数值10^10,再迭代相加100次,大概达到10^40级;long long型也不足以表示,需要使用字符型处理。使用字符串的reverse处理。

#include <iostream>  
#include <string>  
#include <algorithm>          //reverse函数  
using namespace std;  
  
  
string add(string s,string rev)  
{  
    string res="";  
    int k = s.size();  
    int sum,carry=0;  
    int i;  
    for(i=k-1;i>=0;i--)  
    {  
        sum = s[i]+rev[i]-'0'-'0'+carry;  
        res.insert(res.begin(),sum%10+'0');  
        carry = sum/10;  
    }  
    if(carry)res.insert(res.begin(),carry+'0');  
    return res;  
}  
  
bool isPalindromic(string& s,string& rev)  
{  
    rev = s;  
    reverse(rev.begin(),rev.end());         //原字符串反转  
    if(s==rev) return true;  
    s = add(s,rev);  
    return false;  
}  
  
int main()  
{  
    string s,rev;  
    int k;  
    cin>>s>>k;  
    int i;  
    for(i=0;i<k;i++)  
    {  
        if(isPalindromic(s,rev))  
        {  
            break;  
        }  
    }  
    cout<<s<<endl<<i<<endl;   
    return 0;  
}  


pat  1023 注意qsort的用法 (小白书78页)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
char a[30],b[30],c[30];
void dou()
{
    int k=0,jin=0;
    int len=strlen(a);
    for(int i=len-1;i>=0;i--)
    {
        int t=2*(a[i]-'0')+jin;
       // printf("a[i]=%c t=%d\n",a[i],t);
        b[k++]=t%10+'0';
        jin=t/10;
    }
    if(jin)b[k++]=jin+'0';
    b[k]='\0';
    for(int i=0;i<k/2;i++){
        int t=b[i];
        b[i]=b[k-i-1];
        b[k-i-1]=t;
    }
}
int cmp( const void *_a , const void *_b )
{
    char *a=(char* )_a;
    char *b=(char* )_b;
    return strcmp(a,b);
}

bool isequal()
{
    if(strlen(a)!=strlen(c))return false;
    int len=strlen(a);
    qsort(a,len,sizeof(a[0]),cmp);
    qsort(c,len,sizeof(c[0]),cmp);
    for(int i=0;i<len;i++){
       // printf("** %c %c\n",a[i],c[i]);
        if(a[i]!=c[i])return false;
    }
    return true;

}
int main()
{

    while(~scanf("%s",a))
    {
        dou();
        strcpy(c,b);
        if(isequal())puts("Yes");
        else puts("No");
        puts(b);
    }
    return 0;
}


pat1019 注意n=0的情况就好了

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using  namespace std;
int main()
{
    int n,b,a[100];
    while(~scanf("%d%d",&n,&b))
    {
        if(n==0){
            printf("Yes\n0\n");
            continue;
        }
        int k=0,i;
        while(n)
        {
            a[k++]=n%b;
            n/=b;
        }
        for(i=0;i<k;i++)
        {
            if(a[i]!=a[k-i-1])break;
        }
        if(i>=k)puts("Yes");
        else puts("No");
        for(i=k-1;i>=0;i--){
               if(i==0) printf("%d\n",a[i]);
                else printf("%d ",a[i]);
        }

    }
    return 0;
}





pat1060 感觉有坑

#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
int getk(char *a)
{
    int len=strlen(a),i;
    for(i=0;i<len;i++)if(a[i]=='.')break;
    if(a[0]!='0')return i;
    int s=0;
    for(i++;i<len;i++){
            if(a[i]=='0')s++;
            else break;
    }
    return s;
}
int main()
{
    int n;
    char a[110],b[110];
    while(~scanf("%d%s%s",&n,a,b))
    {
        int i=0,j=0,ka,kb;
        int flag=1;
        int lena=strlen(a);
        int lenb=strlen(b);
        ka=getk(a);
        kb=getk(b);
       // printf("* %d %d\n",ka,kb);
        for(i=0;i<lena;i++){
                if(a[i]!='0'&&a[i]!='.')break;
        }
        for(j=0;j<lenb;j++){
                if(b[j]!='0'&&b[j]!='.')break;
        }
       // printf("++ %d %d\n",i,j);
        if(i!=j)flag=0;
        else{
            while(i<j+n)
            {
                if(a[i]!=b[i]){
                    flag=0;
                    break;
                }
                i++;
            }
        }
        for(i=0;i<lena;i++){
                if(a[i]!='0'&&a[i]!='.')break;
        }
        for(j=0;j<lenb;j++){
                if(b[j]!='0'&&b[j]!='.')break;
        }
        if(flag){
            printf("YES 0.");
            while(i<j+n){
                printf("%c",a[i]);
                i++;
            }
            printf("*10^%d\n",ka);
        }
        else {
            printf("NO 0.");
            int k=i+n;
            while(i<k)
            {
                printf("%c",a[i]);
                i++;
            }
            printf("*10^%d 0.",ka);
            k=j+n;
            while(j<k)
            {
                printf("%c",b[j]);
                j++;
            }
            printf("*10^%d\n",kb);
        }
    }

    return 0;
}

/*
3 0.132151 0.000135613
*/

pat1072 两分 T T

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define N 1050
#define INF 0x7ffffff
int n,m,k,ds;
int mapp[N][N];
int vis[N],dist[N],pre[N];//dist[N]就记录了从源点到所有其他顶点之间的最短路径长度
char s1[5],s2[5];
int dis;
int getnum(char *a)
{
    int i=0,s=0;
    if(a[0]=='G')i=1;
    for(;i<strlen(a);i++)s=s*10+a[i]-'0';
    if(a[0]=='G')return n+s;
    else return s;
}

void Dijkstra(int v0)
{
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n+m;i++)
    {
        dist[i]=mapp[v0][i];
        if(dist[i]==INF)pre[i]=-1;
        else pre[i]=v0;
    }
    dist[v0]=0;
    vis[v0]=true;
    int u=v0;
    for(int i=2;i<=n+m;i++)//除源点以外的点
    {
        int min_dist=INF;
      //  printf("u=%d ",u);
        for(int j=1;j<=n+m;j++)
        {
            if(!vis[j]&&dist[j]<min_dist)
            {
                u=j;
                min_dist=dist[j];
            }
        }
     //   printf("v=%d dis=%d\n",u,min_dist);
        vis[u]=true;
        for(int j=1;j<=n+m;j++)
        {
            if(!vis[j]&&dist[u]+mapp[u][j]<dist[j])
            {
                dist[j]=dist[u]+mapp[u][j];
                pre[j]=u;
            }
        }
    }
}

int main()
{
    while(~scanf("%d%d%d%d",&n,&m,&k,&ds))
    {
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<N;j++)mapp[i][j]=INF;
        }
        while(k--)
        {
            scanf("%s%s%d",s1,s2,&dis);
           //printf("%d %d\n",getnum(s1),getnum(s2));
            mapp[getnum(s1)][getnum(s2)]=dis;
            mapp[getnum(s2)][getnum(s1)]=dis;
        }
        Dijkstra(n+1);
        int ansdis=-1,anssum=INF;
        bool isok;
        for(int i=n+1;i<=n+m;i++)
        {
            Dijkstra(i);
            isok=true;
            int sum=0;
            int midis=INF;
            for(int j=1;j<=n;j++)
            {
                if(dist[j]>ds)
                {
                    isok=false;
                    break;
                }
                if(midis>dist[j])midis=dist[j];
                sum+=dist[j];
            }
          //  printf("**%d %d %d %d\n",isok,i,midis,sum);
            if(!isok)break;
            if(midis>ansdis)
            {
                ansdis=midis;
                anssum=sum;
            }
            else if(midis==ansdis&&sum<anssum)anssum=sum;
        }

        if(isok)printf("%d.0 %.1lf\n",ansdis,anssum*1.0/n);
        else puts("No Solution");

    }
    return 0;
}

pat1075 6分 TT

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
struct ss
{
    int s[10];
    int sum;
    int perfect;
    int flag;
    int id;
}a[10010];
bool cmp(ss x,ss y)
{
    if(x.sum==y.sum)
    {
        if(x.perfect==y.perfect)return x.id<y.id;
        return x.perfect>y.perfect;
    }
    return x.sum>y.sum;
}
int main()
{
    int user,pnum,subnum;
    int p[10],i,j;
    while(~scanf("%d%d%d",&user,&pnum,&subnum))
    {
        memset(a,-1,sizeof(a));
        for(i=0;i<10010;i++)a[i].id=i;
        for(i=1;i<=pnum;i++)scanf("%d",&p[i]);
        int t,x,y;
        while(subnum--){
            scanf("%d%d%d",&t,&x,&y);
            a[t].s[x]=max(a[t].s[x],y);
            if(a[t].s[x]!=-1&&a[t].flag==-1)a[t].flag=1;
        }
       // puts("pass");
        for(i=1;i<=user;i++)
        {
            if(a[i].flag==0)continue;
            a[i].sum=a[i].perfect=0;
            for(j=1;j<=pnum;j++)
            {
                if(a[i].s[j]==-1)continue;
                a[i].sum+=a[i].s[j];
                if(a[i].s[j]==p[j])a[i].perfect++;
            }
        }
        sort(a+1,a+user+1,cmp);
        int ranknum=1,per=1000010,tot=1;
        for(i=1;i<=user;i++)
        {

            if(a[i].flag==-1)continue;
         //   printf("* per= %d\n",per);

            if(a[i].sum<per)
            {
                per=a[i].sum;
                ranknum=tot;
            }


            printf("%d %05d %d",ranknum,a[i].id,a[i].sum);
            for(j=1;j<=pnum;j++)
            {
                if(a[i].s[j]==-1)printf(" -");
                else printf(" %d",a[i].s[j]);
            }
         //   printf(" per=%d",a[i].perfect);
            printf("\n");
            tot++;
        }

    }

    return 0;
}

pat1055  21/25一直有个案例超时,不知道怎么优化 

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 100010
vector<int>Age[220];
struct ss
{
    char name[20];
    int age;
    int rich;
}a[maxn];
vector<ss>tmp;
bool cmp(ss x,ss y)
{
    if(x.rich==y.rich)
    {
        if(x.age==y.age)return strcmp(x.name,y.name)<0;
        return x.age<y.age;
    }
    return x.rich>y.rich;
}

int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        for(int i=0;i<220;i++)Age[i].clear();
        for(int i=0;i<n;i++)scanf("%s%d%d",a[i].name,&a[i].age,&a[i].rich);
        sort(a,a+n,cmp);
        for(int i=0;i<n;i++)
        {
            Age[a[i].age].push_back(i);
        }
        int num,x,y;
        for(int kk=1;kk<=k;kk++)
        {
            scanf("%d%d%d",&num,&x,&y);
            tmp.clear();
            for(int i=x;i<=y;i++)
            {
                for(int j=0;j<Age[i].size();j++){
                    tmp.push_back(a[Age[i][j]]);
                }
            }
            sort(tmp.begin(),tmp.end(),cmp);
            printf("Case #%d:\n",kk);
            int sum=0;
            for(int i=0;i<tmp.size();i++)
            {
                printf("%s %d %d\n",tmp[i].name,tmp[i].age,tmp[i].rich);
                sum++;
                if(sum==num)break;
            }
            if(sum==0)puts("None");
        }
    }

    return 0;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值