POJ3126Prime Path
給定兩個(gè)四位素?cái)?shù)a ?b,要求把a(bǔ)變換到b
變換的過程要 每次變換出來的數(shù)都是一個(gè) 四位素?cái)?shù),而且當(dāng)前這步的變換所得的素?cái)?shù) ?與 ?前一步得到的素?cái)?shù) ?只能有一個(gè)位不同,而且每步得到的素?cái)?shù)都不能重復(fù)。
?
///果不其然各種姿勢(shì)操T了,在暴力的時(shí)候,調(diào)用了太多的C++庫文件
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <queue>
using namespace std;
const int maxn=2e5;
bool a[maxn];
bool prime[maxn];
bool vis[maxn];
int step[maxn];
string n,m;
int cnt=0;//四位數(shù)的素?cái)?shù)也就有1061個(gè)
void getprime(){memset(a,false,sizeof(a));memset(prime,false,sizeof(prime));for(int i=2; i<10000; ++i){if(!a[i]){if(i>=1000)prime[i]=true;for(int j=i*i; j<10000; j+=i)a[j]=true;}}
}
void bfs(){memset(vis,false,sizeof(vis));string tmp;queue<string>q;q.push(m);int mm=atoi(m.c_str());vis[mm]=1;step[mm]=0;int k=0;while(!q.empty()){string p=q.front();q.pop();int pp=atoi(p.c_str());if(p==n){printf("%d\n",step[pp]);return ;}for(int i=0; i<=9; ++i){for( k=0; k<4; ++k){tmp.clear();for(int j=0; j<k; ++j) tmp+=p[j];stringstream ss; ss<<i; tmp+=ss.str();//tmp+=std::to_string(i);for(int j=k+1; j<4; ++j) tmp+=p[j];int tmpp=atoi(tmp.c_str());if(prime[tmpp]&&!vis[tmpp]){q.push(tmp);step[tmpp]=step[pp]+1;vis[tmpp]=true;}}}}printf("Impossible\n");
}
int main(){getprime();int t;scanf("%d",&t);while(t--){cin>>m>>n;bfs();}return 0;
}
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <queue>
using namespace std;
const int maxn=2e5;
bool a[maxn];
bool prime[maxn];
bool vis[maxn];
int step[maxn];
int n,m;
int cnt=0;//四位數(shù)的素?cái)?shù)也就有1061個(gè)
void getprime(){memset(a,false,sizeof(a));memset(prime,false,sizeof(prime));for(int i=2; i<10000; ++i){if(!a[i]){if(i>=1000)prime[i]=true;for(int j=i*i; j<10000; j+=i)a[j]=true;}}
}
//將number的倒數(shù)第pos位置變?yōu)関al
int get(int num,int pos,int val){switch(pos){case 0:return num/10*10+val;case 1:return num/100*100+val*10+num%10;case 2:return num/1000*1000+val*100+num%100;case 3:return num%1000+val*1000;}
}
void bfs(){memset(vis,false,sizeof(vis));queue<int>q;q.push(m);vis[m]=1;step[m]=0;int k=0;while(!q.empty()){int p=q.front();q.pop();if(p==n){printf("%d\n",step[p]);return ;}for(int i=0; i<=9; ++i){for( k=0; k<4; ++k){if(k==3&&i==0) continue;int tmp=get(p,k,i);if(prime[tmp]&&!vis[tmp]){q.push(tmp);step[tmp]=step[p]+1;vis[tmp]=true;}}}}printf("Impossible\n");
}
int main(){int t;getprime();scanf("%d",&t);while(t--){scanf("%d%d",&m,&n);bfs();}return 0;
}
POJ 3087?Shuffle'm Up
已知兩堆牌s1和s2的初始狀態(tài), 其牌數(shù)均為c,按給定規(guī)則能將他們相互交叉組合成一堆牌s12,再將s12的最底下的c塊牌歸為s1,最頂?shù)腸塊牌歸為s2,依此循環(huán)下去。
現(xiàn)在輸入s1和s2的初始狀態(tài) 以及 預(yù)想的最終狀態(tài)s12
問s1 s2經(jīng)過多少次洗牌之后,最終能達(dá)到狀態(tài)s12,若永遠(yuǎn)不可能相同,則輸出"-1"。
模擬:
#include <cstdio>
#include <iostream>
#include <queue>
#include <map>
#include <cstring>
using namespace std;
int main()
{int t;scanf("%d",&t);for(int ca=1;ca<=t;++ca){int n;char s1[1005],s2[1005],en[10000];map<string,bool >m;scanf("%d",&n);scanf("%s",s1);scanf("%s",s2);scanf("%s",en);int step=0;int times=1000,ti=0;while(true){ti++;char s[1000];int pc=0;for(int i=0;i<n;++i){s[pc++]=s2[i];s[pc++]=s1[i];}s[pc]='\0';step++;if(!strcmp(s,en)){printf("%d %d\n",ca,step);break;}if(m[s]){printf("%d %d\n",ca,-1);break;}m[s]=true;strncpy(s1,s,n);s1[n]='\0';strncpy(s2,s+n,n);s2[n]='\0';if(ti==times){printf("%d %d\n",ca,-1);break;}}}
return 0;
}
dfs:
#include <cstdio>
#include <iostream>
#include <queue>
#include <map>
#include <cstring>
using namespace std;
int ans,n;
map<string,int>m;
char s1[200],s2[200],s3[200];
void dfs(char s[],int step){if((ans=-1&&step>=ans)||m[s])return;if(m[s])return;if(!strcmp(s,s3)){ans=step;return ;}m[s]=true;char ss[200]="";int op=0;for(int i=0;i<n;++i){ss[op++]=s[i+n];ss[op++]=s[i];}dfs(ss,step+1);
}
int main(){int t;char ss[200];scanf("%d",&t);for(int ca=1;ca<=t;++ca){ans=-1;m.clear();// map<>scanf("%d",&n);scanf("%s",s1);scanf("%s",s2);scanf("%s",ss);char s[200];int op=0;for(int i=0;i<n;++i){s[op++]=s1[i];s[op++]=s2[i];}dfs(s,1);printf("%d %d\n",ca,ans);}
}
UVA 11624?Fire!
題意:幫助joe走出一個(gè)大火蔓延的迷宮,其中joe每分鐘可往上下左右四個(gè)方向之一走,所有著火的格子都會(huì)蔓延(空格與著火格有公共邊,下一分鐘這個(gè)空格也會(huì)著火)。迷宮中有一些障礙格,joe和火都無法進(jìn)入,當(dāng)joe走到一個(gè)邊界的格子我們認(rèn)為他走出了迷宮
?輸出R行C列的迷宮,#表示墻,.表示空地,J表示joe,F是著火格
?如果能走出,輸出最少時(shí)間否則,impossible
感覺很經(jīng)典的一個(gè)問題,在處理每個(gè)點(diǎn)著火的時(shí)間的時(shí)候,卻發(fā)現(xiàn)假若當(dāng)前這個(gè)點(diǎn)之前已經(jīng)被火著過一次怎么辦了,在一想這就是簡(jiǎn)單的bfs最優(yōu)性質(zhì)決定的,用寬搜的時(shí)候就已經(jīng)保證了在搜索過的著火點(diǎn)已經(jīng)是最優(yōu)的了
?
#include <iostream>
#include<cstdio>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn=(int)1e3+10;
char map[maxn][maxn];
int step[maxn][maxn];
int vis[maxn][maxn];
int n,m;
ll inf=0x3f3f3f3f;
int dir[4][2]={{1,0},{0,1},{0,-1},{-1,0}};queue<pair<int,int> >q;void clear(queue<pair<int,int> >& q){queue<pair<int,int> > empty;swap(empty,q);}
void bfs_fire(){while(!q.empty()){pair<int,int> p=q.front();q.pop();int x=p.first,y=p.second;// vis[x][y]=1;//vis[p.first][p.second]=1; 如果一直用first second去查找肯定會(huì)耗費(fèi)時(shí)間pair<int,int> tmp;for(int i=0;i<4;++i){int dx=x+dir[i][0];int dy=y+dir[i][1];if(dx<1||dx>n||dy<1||dy>m||step[dx][dy]!=inf)continue;if(map[dx][dy]=='#')continue;tmp.first=dx,tmp.second=dy;step[dx][dy]=step[x][y]+1;q.push(tmp);}}
}
int pe[maxn][maxn];
void bfs_person(){pair<int,int > p;while(!q.empty()){p=q.front();q.pop(); int x=p.first,y=p.second;if(x==1||x==n||y==1||y==m){printf("%d\n",pe[x][y]+1);return ;}// vis[x][y]=1;for(int i=0;i<4;++i){int dx=x+dir[i][0];int dy=y+dir[i][1];if(dx<1||dx>n||dy<1||dy>m||pe[dx][dy]!=inf)continue;if(map[dx][dy]=='#')continue;if( (pe[x][y]+1<step[dx][dy]) ){//&&step[dx][dy]!=inf wa //加上這個(gè)!=inf開始是為了防止更新到障礙物所在的方格,其實(shí)上面的!=#已經(jīng)判斷了,不加也可以,不過加上他之后竟然wa掉,那就是說存在數(shù)據(jù)火到不了的網(wǎng)格人可以到,障礙物把火源包圍了的這種情況pe[dx][dy]=pe[x][y]+1;q.push(make_pair(dx,dy));}}}printf("IMPOSSIBLE\n");return ;
}
void solve(){memset(step,inf,sizeof(step));//memset(vis,0,sizeof(vis));while(!q.empty())q.pop();//clear(q);// for(int i=1;i<=n;++i){// for(int j=1;j<=m;++j)// cout<<map[i][j];// cout<<endl;// }for(int i=1;i<=n;++i)for(int j=1;j<=m;++j){if(map[i][j]=='F'){step[i][j]=0;q.push(make_pair(i,j));}}bfs_fire();// for(int i=1;i<=n;++i){// for(int j=1;j<=m;++j){// cout<<step[i][j]<<' ';// }// cout<<endl;// }// memset(vis,0,sizeof(vis));memset(pe,inf,sizeof(pe));// clear(q);for(int i=1;i<=n;++i)for(int j=1;j<=m;++j){if(map[i][j]=='J'){pe[i][j]=0;q.push(make_pair(i,j));break;}}bfs_person();// for(int i=1;i<=n;++i){// for(int j=1;j<=m;++j)// cout<<pe[i][j]<<' ';// cout<<endl;// }//return;
}
int main(){int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(int i=1;i<=n;++i){scanf("%s",(map[i]+1));}solve();}return 0;
}
//除了上面的那個(gè)inf問題還有就是開始定義了兩個(gè)vis的初始化,一開始就T掉,
POJ 3984?迷宮問題
定義一個(gè)二維數(shù)組:
int maze[5][5] = {
?? ?0, 1, 0, 0, 0,
?? ?0, 1, 0, 1, 0,
?? ?0, 0, 0, 0, 0,
?? ?0, 1, 1, 1, 0,
?? ?0, 0, 0, 1, 0,
};
它表示一個(gè)迷宮,其中的1表示墻壁,0表示可以走的路,只能橫著走或豎著走,不能斜著走,要求編程序找出從左上角到右下角的最短路線。
Input
一個(gè)5 × 5的二維數(shù)組,表示一個(gè)迷宮。數(shù)據(jù)保證有唯一解。
Output
左上角到右下角的最短路徑,格式如樣例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
#include <cstdio>
#include <iostream>
#include <queue>
//#include <bits/stdc++.h>
#include <cstring>
using namespace std;
int mat[5][5];
int dir[5][2]={{1,0},{0,1},{0,-1},{-1,0}};
struct node{
int x,y,pre;
}point[100];
void dfs(node p)
{if(p.pre==-1){printf("(%d, %d)\n",p.x,p.y);return;}dfs(point[p.pre]);printf("(%d, %d)\n",p.x,p.y);
}
void bfs()
{int x,y,dx,dy,pre=0,cur=1;//queue<node> q;point[0].x=0,point[0].y=0,point[0].pre=-1;mat[0][0]=1;while(pre<=cur){if(point[pre].x==4&&point[pre].y==4){dfs(point[pre]);return ;}for(int i=0;i<4;++i){dx=point[pre].x+dir[i][0];dy=point[pre].y+dir[i][1];if(dx<0||dx>=5||dy<0||dy>=5||mat[dx][dy])continue;point[cur].x=dx,point[cur].y=dy,point[cur].pre=pre;++cur;}++pre;}
}
int main()
{for(int i=0;i<5;++i)for(int j=0;j<5;++j)scanf("%d",&mat[i][j]);bfs();
return 0;
}
?
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀
總結(jié)
以上是生活随笔為你收集整理的【POJ3126 Prime Path】【POJ 3087 Shuffle'm Up】【UVA 11624 Fire!】【POJ 3984 迷宫问题】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。