今天只刷出来三题。
明天下午组内又有测试了,肿么办呀,搜索和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;
}