19/7/2012 ICPC培训 第四天

来源:互联网 发布:linux 查看用户组 编辑:程序博客网 时间:2024/05/01 21:59

今天只刷出来三题大哭

明天下午组内又有测试了,肿么办呀,搜索和DP。

说说今天吧。

这三题都是以前看过但没做出来的题,也根本就没尝试去做,就觉得做不出来!

第一题(HDU4039)。

这题花了6个小时左右抓狂。其实,前两个小时代码就搞定了,可是有一处小错,一直TLE呀。

在Floyd()中把两个if判断条件没写好呀。明明算法是对的,可是代码逻辑就是没能那样写出来!

这种错误还很难找!!!

这题听说可以用搜索,可是木有思路。于是乎,我就建图了,然后借用Floyd算法搞定的。当然,

这其中还有怎么按字典序输出,怎么判断要输出的个数以及怎么控制按格式输出。

代码:

也可以看看这个代码:点击打开链接

#include<iostream>using namespace std;const int maxLen=16;const int maxNum=2001;bool map[maxNum][maxNum];  //建图 int result[maxNum][maxNum];  //result[i][j]表示i、j的共同朋友数 int numOfRelation,quary,numOfName,cas=1;char temp[maxNum][maxLen];  //存放字典序的人 struct node{    char front[maxLen];    char back[maxLen];}help[maxNum/2];  //暂时存放朋友关系 int findIndex(char c[])  //寻找ch[]在temp[]中的下标 {    for(int i=0;i<numOfName;i++)    {        if(strcmp(c,temp[i])==0)        {            return i;        }    }        return -1;}    void initInput()  //输入认识关系,并将不同的人存放在temp[]中 {    int index;        numOfName=0;   //存放在temp[]中的不同名字个数     for(int i=0;i<numOfRelation;i++)    {        scanf("%s%s",&help[i].front,&help[i].back);                index=findIndex(help[i].front);        if(index==-1)        {            strcpy(temp[numOfName++],help[i].front);        }                index=findIndex(help[i].back);        if(index==-1)        {            strcpy(temp[numOfName++],help[i].back);        }    }   }void bubbleSort()  //将temp中的人按字典序排序 {    char ch[maxLen];        for(int i=0;i<numOfName;i++)    {        for(int j=numOfName-1;j>i;j--)        {            if(strcmp(temp[j],temp[j-1])==-1)  //temp[j]<temp[j-1]             {                strcpy(ch,temp[j]);                strcpy(temp[j],temp[j-1]);                strcpy(temp[j-1],ch);            }        }    }}void buildMap()   //建图 ,无向图 {    memset(map,false,sizeof(map));        int row,col;    for(int i=0;i<numOfRelation;i++)    {        row=findIndex(help[i].front);        col=findIndex(help[i].back);                if(row!=col)   //题目要求,自己和自己不是朋友         {            map[row][col]=map[col][row]=true;        }    }    }       void Floyd()  //算法变形,加优化 {    memset(result,0,sizeof(result));        for(int k=0;k<numOfName;k++)     {         for(int i=0;i<numOfName;i++)        {            //if(i==k) continue;             if(!map[i][k]) continue;             for(int j=0;j<numOfName;j++)            {                //if(j==k || j==i) continue;                 if(map[k][j] && !map[i][j] && i!=j)  //k就是i、j都认识的人                 {                    result[i][j]++;                }            }        }    }}               void output()  //输出 {    printf("Case %d:\n",cas++);        char ch[maxLen];    int index,maxResult,i,j;        for(i=0;i<quary;i++)    {        scanf("%s",&ch);                index=findIndex(ch);                maxResult=0;         for(j=0;j<numOfName;j++)        {            if(index!=j)            {                 maxResult=maxResult>result[index][j]?maxResult:result[index][j];            }         }                if(maxResult==0)        {            printf("-\n");            continue;        }                int num=0;        int rem[maxNum/2];         for(j=0;j<numOfName;j++)        {            if(index!=j && maxResult==result[index][j])            {                rem[num++]=j;             }        }                for(j=0;j<num-1;j++)        {            printf("%s ",temp[rem[j]]);        }         printf("%s\n",temp[rem[num-1]]);    }}       /*   也可以去掉注释,然后把函数Floyd()和output()注释  掉,同样能过,当然主函数中的调用也要注释掉,另外,  全局变量result[][]也注释掉   void getResult(){    printf("Case %d:\n",cas++);        int index,maxResult,i,j,k;    char ch[maxLen];     int result[maxNum],rem[maxNum/2];          for(i=0;i<quary;i++)    {         maxResult=0;        memset(result,0,sizeof(result));                scanf("%s",&ch);                index=findIndex(ch);                for(j=0;j<numOfName;j++)        {            if(!map[index][j]) continue;             for(k=0;k<numOfName;k++)            {                if(!map[j][k] || map[index][k] || index==k) continue;                                result[k]++;                                maxResult=maxResult>result[k]?maxResult:result[k];            }        }                if(maxResult==0)        {            printf("-\n");            continue;        }                int num=0;        for(j=0;j<numOfName;j++)        {            if(index!=j && maxResult==result[j])            {                rem[num++]=j;             }        }                for(j=0;j<num-1;j++)        {            printf("%s ",temp[rem[j]]);        }         printf("%s\n",temp[rem[num-1]]);    }}      */                           int main(){    int tCase;        scanf("%d",&tCase);     while(tCase--)    {        scanf("%d%d",&numOfRelation,&quary);                initInput();                bubbleSort();                buildMap();                Floyd();                   output();                //getResult();    }        return 0;}

第二题(HDU1572)

个人觉得这题意思不是很清楚,没说是否可以重复走。其他就是暴力dfs了。

代码:

#include<iostream>#include<cstring>using namespace std;const int INF=0x7fffffff;const int maxCity=30;const int maxPeople=7;double map[maxCity][maxCity],minLen;bool visit[maxCity][maxCity],canVisit[maxCity];int exist[maxPeople];int nCity,nPeople;void input(){    for(int i=0;i<nCity;i++)    {        for(int j=0;j<nCity;j++)        {            cin>>map[i][j];        }    }        cin>>nPeople;        for(int j=0;j<nPeople;j++)    {        cin>>exist[j];    }}bool visitAll(){    for(int i=0;i<nPeople;i++)    {        if(canVisit[exist[i]]==false)        {            return false;        }    }        return true;}bool notVisit(int x){    if(canVisit[x]==false)    {        return true;    }        return false;}void dfs(int x,double len){    if(visitAll())    {        minLen=minLen>len?len:minLen;        return;    }        for(int i=0;i<nPeople;i++)    {                if(!visit[x][exist[i]] && notVisit(exist[i]))        {            canVisit[exist[i]]=true;            visit[x][exist[i]]=true;            len+=map[x][exist[i]];            dfs(exist[i],len);            canVisit[exist[i]]=false;            visit[x][exist[i]]=false;            len-=map[x][exist[i]];        }    }}  int main(){    while(cin>>nCity,nCity)    {        input();                minLen=INF;        memset(canVisit,false,sizeof(canVisit));        canVisit[0]=true;        memset(visit,false,sizeof(visit));        visit[0][0]=true;        dfs(0,0);                cout<<minLen<<endl;    }        return 0;}

第三题(HDU1372)

这题看过一直没明白啥意思!马走日就马走日呗,还说的那么复杂。自己英语不好,还搞啥那么

那么难懂的英语。

苦逼的是,刚开始居然想着用dfs来写,结果你懂的,半天没出结果。2B了。。。

然后用bfs加上优先级队列过了。

代码:

#include<iostream>#include<cstring>#include<queue>using namespace std; const int len=9;const int INF=0x7fffffff;const int help[][2]={{1,-2},{2,-1},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2}}; bool visit[len][len],flag;int minStep; struct node{    int x,y,step;        friend bool operator < (const node a,const node b)    {        return a.step>b.step;    } }start,end;bool canVisit(int x,int y){    if(x>=1 && x<=8 && y>=1 && y<=8 && !visit[x][y])    {        return true;    }        return false;}  void bfs() {    memset(visit,false,sizeof(visit));    visit[start.x][start.y]=true;        priority_queue<node> myQ;    myQ.push(start);        node temp1,temp2;    flag=false;    minStep=0;    while(!myQ.empty() && !flag)    {        temp1=myQ.top();        myQ.pop();                 for(int i=0;i<8;i++)        {            temp2.x=temp1.x+help[i][0];            temp2.y=temp1.y+help[i][1];                        if(!canVisit(temp2.x,temp2.y)) continue;                        visit[temp2.x][temp2.y]=true;             temp2.step=temp1.step+1;                         if(temp2.x==end.x && temp2.y==end.y)            {                flag=true;                minStep=temp2.step;                 continue;             }                        myQ.push(temp2);         }     }}           int main() {    char ch1[3],ch2[3];        while(cin>>ch1>>ch2)    {        start.y=ch1[0]-'a'+1;        start.x=ch1[1]-'0';        start.step=0;        end.y=ch2[0]-'a'+1;        end.x=ch2[1]-'0';                bfs();                 cout<<"To get from "<<ch1<<" to "<<ch2<<" takes "<<minStep<<" knight moves."<<endl;     }        return 0;}


原创粉丝点击