2020-07-06 热身训练赛(六)
A.Rush Hour Puzzle
题意:A是有个6*6的格子,里面有1*3的火车和1*2的小汽车,他们不能拐弯,让着通过移动这些小车,把编号为1的小汽车从(3,6)这个格子移出去,问能否在10步之内移动出去,输出步数或者-1。
解:这个题想的是迭代加深搜索,结果写的是个普通搜索,原因是写着写着忘了😥,不过没多大问题,因为写完之后运行了十多秒,就加了几个剪枝,运行的时候总出小问题,就改了好久,感觉自己代码写的超啰嗦。
有两种-1的情况可以直接判断,一是编号为1的小车不在第三行,二是编号为1的小车的右侧有横向行驶的小车,这两种情况直接输出-1即可。
在迭代加深搜索时,判断状态我用的结构体,存储每个车的左或上端点,那么每次移动的时候,就看一下当前要移动的节点移动后的位置是否与爷爷状态的这个节点的位置相同,如果相同,那就相当于往返移动了一次,就可以不用移动。因此搜索时需要传递两个状态:父亲状态和爷爷状态。
剪枝:1.小红车右面没有任何障碍的时候,判断直接移动出去的步数是否大于10,然后更新答案,return
2.如果当前位置直接移动出去的步数加上已经走过的步数大于10,就不必再搜索
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<map> 5 using namespace std; 6 int a[7][7],n,ans=0x7fffffff; 7 8 struct node{ 9 int x,y; 10 int len; 11 bool ang;//0横着.1竖着 12 bool operator != (const node &u)const{ 13 if(x!=u.x||y!=u.y)return 1; 14 return 0; 15 } 16 }car[20]; 17 18 struct State{ 19 node w[20]; 20 bool operator != (const State &u)const{ 21 for(int i=1;i<=n;i++){ 22 if(w[i]!=u.w[i])return 1; 23 } 24 return 0; 25 } 26 }; 27 28 node make_node(int x,int y,int len,bool ang){ 29 node res; 30 res.x=x;res.y=y;res.len=len;res.ang=ang; 31 return res; 32 } 33 34 State make_sta(const node *c){ 35 State res; 36 for(int i=1;i<=n;i++){ 37 res.w[i]=c[i]; 38 } 39 return res; 40 } 41 42 bool Judge(const State u){ 43 if(u.w[1].x==3&&u.w[1].y==5) 44 return 1; 45 return 0; 46 } 47 48 bool check(int x,int y,const State &u){ 49 for(int i=1;i<=n;i++){ 50 if(!u.w[i].ang && u.w[i].x==x && u.w[i].y<=y && u.w[i].y+u.w[i].len-1>=y) 51 return 0; 52 if(u.w[i].ang && u.w[i].y==y && u.w[i].x<=x && u.w[i].x+u.w[i].len-1>=x) 53 return 0; 54 } 55 return 1; 56 } 57 58 void dfs(int deep,const State &fa,const State &prefa){ 59 if(Judge(fa)){ 60 ans=min(ans,deep+1); 61 return; 62 } 63 if((7-fa.w[1].y)>10-deep+1)return; 64 bool flag=0; 65 for(int i=2;i<=n;i++){ 66 if(!fa.w[i].ang&&fa.w[i].y>fa.w[1].y){ 67 flag=1; 68 break; 69 } 70 if(fa.w[i].ang && fa.w[i].y>=fa.w[1].y+2 && fa.w[i].x<=3 && fa.w[i].x+fa.w[i].len-1>=3){ 71 flag=1; 72 break; 73 } 74 } 75 if(!flag){ 76 ans=min(ans,deep-1+7-fa.w[1].y); 77 return; 78 } 79 if(deep==9){ 80 return; 81 } 82 State now=make_sta(fa.w); 83 for(int i=1;i<=n;i++){ 84 node u=now.w[i]; 85 if(!u.ang&&(u.y+u.len-1<6)){//向右 86 if(check(now.w[i].x,now.w[i].y+now.w[i].len,now)){ 87 now.w[i].y++; 88 if(prefa.w[i]!=now.w[i]){ 89 dfs(deep+1,now,fa); 90 } 91 now.w[i].y--; 92 } 93 94 } 95 if(i!=1&&!u.ang&&(u.y>1)){//向左 96 if(check(now.w[i].x,now.w[i].y-1,now)){ 97 now.w[i].y--; 98 if(prefa.w[i]!=now.w[i]){ 99 dfs(deep+1,now,fa); 100 } 101 now.w[i].y++; 102 } 103 104 } 105 if(u.ang&&(u.x+u.len-1<6)){//向下 106 if(check(now.w[i].x+now.w[i].len,now.w[i].y,now)){ 107 now.w[i].x++; 108 if(prefa.w[i]!=now.w[i]){ 109 dfs(deep+1,now,fa); 110 } 111 now.w[i].x--; 112 } 113 114 } 115 if(u.ang&&(u.x>1)){//向上 116 if(check(now.w[i].x-1,now.w[i].y,now)){ 117 now.w[i].x--; 118 if(prefa.w[i]!=now.w[i]){ 119 dfs(deep+1,now,fa); 120 } 121 now.w[i].x++; 122 } 123 124 } 125 } 126 } 127 128 int main(){ 129 freopen("Cola.txt","r",stdin); 130 int cnt=0; 131 for(int i=1;i<=6;i++) 132 for(int j=1;j<=6;j++){ 133 scanf("%d",&a[i][j]); 134 n=max(a[i][j],n); 135 } 136 bool flag=0; 137 for(int i=1;i<6;i++){ 138 if(a[3][i]==1&&a[3][i+1]==1)flag=1; 139 } 140 if(!flag){ 141 puts("-1"); 142 return 0; 143 } 144 for(int i=1;i<=n;i++){ 145 flag=0; 146 for(int j=1;j<=6;j++){ 147 for(int k=1;k<=6;k++){ 148 if(a[j][k]==i){ 149 if(k+1<=6&&a[j][k+1]==i&&(k+2>6||a[j][k+2]!=i)){//2格横着 150 car[i]=make_node(j,k,2,0); 151 flag=1; 152 break; 153 } 154 if(k+2<=6&&a[j][k+1]==i&&a[j][k+2]==i){//3格横着 155 car[i]=make_node(j,k,3,0); 156 flag=1; 157 break; 158 } 159 if(j+1<=6&&a[j+1][k]==i&&(j+2>6||a[j+2][k]!=i)){//2格竖着 160 car[i]=make_node(j,k,2,1); 161 flag=1; 162 break; 163 } 164 if(j+2<=6&&a[j+1][k]==i&&a[j+2][k]==i){//3格竖着 165 car[i]=make_node(j,k,3,1); 166 flag=1; 167 break; 168 } 169 } 170 } 171 if(flag)break; 172 } 173 } 174 for(int i=2;i<=n;i++){ 175 if(!car[i].ang&&car[i].x==car[1].x&&car[i].y>=car[1].y){ 176 puts("-1"); 177 return 0; 178 } 179 } 180 State now=make_sta(car); 181 dfs(1,now,now); 182 if(ans<=10)printf("%d\n",ans); 183 else puts("-1"); 184 return 0; 185 }
D.Tapioka
题意:给出三个字符串,删除其中的“bubble” 和 “tapioka” ,再按照原来的顺序输出,删没了就输出"nothing"
解:小水题
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 char s[5][40]; 6 bool flag[5]; 7 int main(){ 8 int cnt=3; 9 for(int i=1;i<=3;i++)scanf("%s",s[i]); 10 for(int i=1;i<=3;i++){ 11 if(!strcmp(s[i],"bubble")||!strcmp(s[i],"tapioka")){ 12 flag[i]=1; 13 cnt--; 14 } 15 } 16 if(!cnt){puts("nothing");} 17 else{ 18 for(int i=1;i<=3;i++){ 19 if(!flag[i])printf("%s ",s[i]); 20 } 21 } 22 puts(""); 23 return 0; 24 }