携程 决赛 第一题 Crossword

//真是郁闷的一晚上
//比赛时看到这题是就感觉会做,感觉思路清晰 就去准备找第二题 ,因为感觉第二题是个经典问题,(我不会计算几何),就去搜索了下,然后找到求最小面积的,改来改去,一直Wa
// 然后就只剩下一个小时了 ,我决定放弃它,去写第一题 就是这题,然后整栋楼离奇断网什么的、、还调试了好久、、

// 思路 :将K个字符串算出Hash值 保存,同时要记录串的长度
// 这样在搜索时候 就可以根据Hash和字符串长度来筛选出某一位置可以填哪些串 因为串的起始和结束位置也能判断可以填的串可以多长
// 这样就是暴力搜索了
// 我对M个串位置进行了排序,然后我发现排不排序都一样,无所谓的

#include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<iostream> #include<algorithm> #include<functional> #include<cmath> #include <vector> using namespace std; vector <string> Hs[1000]; vector <int > len[1000]; int Map[40][40]; int n,m; struct node { int x1,y1,x2,y2,k; bool operator <(const node&t) const { if(x1==t.x1) return x2<t.x2; return x1<t.x1; } } st[120]; int K; int flag; char str[100]; int ar[40]; void dfs(int index) { if(index==m) { flag=1; return ; } int x1=st[index].x1,x2=st[index].x2; int y1=st[index].y1,y2=st[index].y2; int k=st[index].k; int le=x1-x2+y1-y2; if(le<0) le=-le; le++; for(int i=0; i<Hs[k].size(); i++) if(le==len[k][i]) { if(x1==x2) { int dir=y1<y2?1:-1; int j,id=0; for(j=y1; j!=y2; id++, j+=dir) if(Map[x1][j]&&Map[x1][j]!=Hs[k][i][id]) break; if(j==y2) { id=0; for(j=y1; j!=y2; id++, j+=dir) if(!Map[x1][j]) { Map[x1][j]=Hs[k][i][id]; ar[j]=1; } else ar[j]=0; if(!Map[x1][j]) { Map[x1][j]=Hs[k][i][id]; ar[j]=1; } else ar[j]=0; dfs(index+1); if(flag) return; for(j=y1; j!=y2; j+=dir) if(ar[j]) Map[x1][j]=0; } } else if(y1==y2) { int dir=x1<x2?1:-1; int j,id=0; for(j=x1; j!=x2; id++, j+=dir) if(Map[j][y1]&&Map[j][y1]!=Hs[k][i][id]) break; if(j==x2) { id=0; for(j=x1; j!=x2; id++,j+=dir) if(!Map[j][y1]) { Map[j][y1]=Hs[k][i][id]; ar[j]=1; } else ar[j]=0; if(!Map[j][y1]) { Map[j][y1]=Hs[k][i][id]; ar[j]=1; } else ar[j]=0; dfs(index+1); if(flag) return; for(j=x1; j!=x2; j+=dir) if(ar[j]) Map[j][y1]=0; } } } } int main() { int i,j; int Case=1; while(scanf("%d %d",&n,&m),n|m) { if(Case++!=1) printf("\n"); for(i=0; i<m; i++) scanf("%d %d %d %d %d",&st[i].x1,&st[i].y1,&st[i].x2,&st[i].y2,&st[i].k); sort(st,st+m); scanf("%d",&K); for(i=0; i<K; i++) { scanf("%s",str); int hs=0; for(j=0; str[j]!='\0'; j++) hs=(hs*33+str[j])%997; Hs[hs].push_back(str); len[hs].push_back(j); } memset(Map,0,sizeof(Map)); flag=0; dfs(0); if(flag) for(i=1; i<=n; i++) { for(j=1; j<n; j++) if(Map[i][j]) printf("%c",Map[i][j]); else printf(" "); if(Map[i][j]) printf("%c\n",Map[i][j]); else printf(" \n"); } } return 0; }

 

转载于:https://www.cnblogs.com/372465774y/p/3665204.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值