标签:i++ 前置 -- cost continue 简单搜索 memset pat flag
目录
从大二下学期开始学算法 一开始就知道这个专题 一开始对于这个专题里的所有问题感觉都好难啊。。就直接放弃了 看lrj的书 现在看到这个专题还挺唏嘘的吧 突然觉得思维和想法也不是很难 果然是那个时候心不静&还是储量不够吗2333333
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m;
char a[maxn][maxn];
int ans;
bool row[maxn];
void dfs(int x,int step){
if(step>=m){
ans++;
return ;
}
if(x>=n){
return ;
}
for(int i=0;i<n;i++){ //x是行
if(a[x][i]==‘#‘&&!row[i]){
row[i]=true;
dfs(x+1,step+1);
row[i]=false;
}
}
dfs(x+1,step);
}
int main() {
//freopen("test","r",stdin);
//freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(cin>>n>>m&&n!=-1){
ans=0;
memset(row,false, sizeof(row));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
cin>>a[i][j];
}
dfs(0,0);
cout<<ans<<endl;
}
return 0;
}
一个水平上下左右&垂直上下的bfs第一次看的时候没看懂题目23333
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m,l,r,c;
int step[maxn][maxn][maxn];
struct node{ //node是第几层 r c表示几行几列
int x,y,z;
char v;
};
char maze[maxn][maxn][maxn];
int dx[]={1,-1,0,0,0,0};
int dy[]={0,0,1,-1,0,0};
int dz[]={0,0,0,0,1,-1};
int main() {
//freopen("test","r",stdin);
//freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(cin>>l>>r>>c&&l+r+c){
int s_l,s_r,s_c;
int e_l,e_r,e_c;
node a;
node Begin;
node End;
bool ok=false;
memset(step,0, sizeof(step));
for(int i=0;i<l;i++) {
for (int j = 0; j < r; j++) {
for (int k = 0; k < c; k++) {
cin >>a.v;
a.x=i;
a.y=j;
a.z=k;
maze[i][j][k]=a.v;
if (a.v == ‘S‘) {
Begin=a;
}
if (a.v == ‘E‘) {
End=a;
}
}
}
}
queue<node> q;
q.push(Begin);
while(q.size()){
node temp=q.front();
q.pop();
if(temp.x==End.x&&temp.y==End.y&&temp.z==End.z){
cout<<"Escaped in "<<step[End.x][End.y][End.z]<<" minute(s)."<<endl;
ok=true;
break;
}
for(int i=0;i<6;i++){
node nxt=temp;
nxt.x+=dx[i];
nxt.y+=dy[i];
nxt.z+=dz[i];
if(nxt.x>=0&&nxt.x<l&&nxt.y>=0&&nxt.y<r&&nxt.z>=0&&nxt.z<c&&maze[nxt.x][nxt.y][nxt.z]!=‘#‘){
q.push(nxt);
step[nxt.x][nxt.y][nxt.z]=step[temp.x][temp.y][temp.z]+1;
maze[nxt.x][nxt.y][nxt.z]=‘#‘;
}
}
}
if(!ok){
cout<<"Trapped!"<<endl;
}
}
return 0;
}
没啥好讲的 简单bfs就完事了
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1E5;
int T,n,m;
int step[INF*2];
int main() {
//freopen("test","r",stdin);
//freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(cin>>n>>m){
queue<int> q;
q.push(n);
step[n]=1;
while(q.size()){
int temp=q.front();
q.pop();
if(temp==m){
cout<<step[m]-1<<endl;
break;
}
if(temp*2<INF*2&&!step[temp*2]){
q.push(temp*2);
step[temp*2]=step[temp]+1;
}
if(temp-1>=0&&!step[temp-1]){
q.push(temp-1);
step[temp-1]=step[temp]+1;
}
if(temp+1<INF&&!step[temp+1]){
q.push(temp+1);
step[temp+1]=step[temp]+1;
}
}
}
return 0;
}
这个就是传说中的状态转移啦 。就是说前一层的状态一定取决于下一层的状态 也就是说只要确定第一层的状态 其他剩下的状态都是确定的 同时这个问题也是开关问题的延伸(二维开关问题)
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m;
int a[maxn][maxn];
const int dx[]={-1,1,0,0,0};
const int dy[]={0,0,0,-1,1};
int opt[maxn][maxn];
int filp[maxn][maxn];
int get_color(int x,int y){
int v=a[x][y];
for(int i=0;i<5;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m){
v+=filp[nx][ny];
}
}
return v%2;
}
int clac(){
for(int i=1;i<n;i++){
for(int j=0;j<m;j++){
if(get_color(i-1,j)!=0){
filp[i][j]=1;
}
}
}
for(int i=0;i<m;i++) {
if (get_color(n - 1, i) != 0) {
return -1;
}
}
int res=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
res+=filp[i][j];
}
}
return res;
}
int main() {
//freopen("test","r",stdin);
//freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(cin>>n>>m){
int res=-1;
int num;
for(int i=0;i<n;i++) {
for (int j = 0; j < m; j++) {
cin >> a[i][j];
}
}
for(int i=0;i<1<<m;i++){
memset(filp,0, sizeof(filp));
for(int j=0;j<m;j++){
filp[0][m-j-1]=i>>j&1;
}
num=clac();
if(num>=0&&(res<0||res>num)){
res=num;
memcpy(opt,filp, sizeof(filp));
}
}
if(res>=0) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (j == 0)
cout << opt[i][j];
else
cout << " " << opt[i][j];
}
cout << endl;
}
} else cout<<"IMPOSSIBLE"<<endl;
}
return 0;
}
题意:给定一个数字 找一串01串能整除这个数 其实这个题目的位数没有那么可怕 。(至少没有100位) longlong是够用的
所以说01串直接bfs可得
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
ll T,n,m;
char a[maxn][maxn];
queue<ll> q;
int main() {
//freopen("test","r",stdin);
//freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(cin>>n&&n){
while(q.size())
q.pop();
q.push(1);
while(q.size()){
ll temp=q.front();
q.pop();
if(temp%n==0){
cout<<temp<<endl;
break;
}
q.push(temp*10);
q.push(temp*10+1);
}
}
return 0;
}
先打一个素数表
之后bfs一位一位搜啊。。
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include<sstream>
#include<ctype.h>
using namespace std;
const int maxn=10000+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m;
map<int,int> mp;
queue<int> q;
int vis[maxn];
int main() {
freopen("test","r",stdin);
freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
for(int i=1000;i<=9999;i++){
bool flag=true;
for(int j=2;j*j<=i;j++){
if(i%j==0){
flag=false;
break;
}
}
if(flag)
mp[i]=1;
}
cin>>T;
while(T--){
cin>>n>>m;
int a,b,c,d;
memset(vis,0, sizeof(vis));
while(q.size()) {
q.pop();
}
vis[n]=1;
q.push(n);
while(q.size()){
int temp=q.front();
q.pop();
if(temp==m) {
cout << vis[m] << endl;
break;
}
a=temp/1000;
b=temp/100%10;
c=temp/10%10;
d=temp%10;
for(int i=1;i<=9;i++){
if(mp[i*1000+b*100+c*10+d]==1&&vis[i*1000+b*100+c*10+d]==0){
q.push(i*1000+b*100+c*10+d);
vis[i*1000+b*100+c*10+d]=vis[temp]+1;
}
}
for(int i=1;i<=9;i++){
if(mp[a*1000+i*100+c*10+d]==1&&vis[a*1000+i*100+c*10+d]==0){
q.push(a*1000+i*100+c*10+d);
vis[a*1000+i*100+c*10+d]=vis[temp]+1;
}
}
for(int i=1;i<=9;i++){
if(mp[a*1000+b*100+i*10+d]==1&&vis[a*1000+b*100+i*10+d]==0){
q.push(a*1000+b*100+i*10+d);
vis[a*1000+b*100+i*10+d]=vis[temp]+1;
}
}
for(int i=1;i<=9;i++){
if(mp[a*1000+b*100+c*10+i]==1&&vis[a*1000+b*100+c*10+i]==0){
q.push(a*1000+b*100+c*10+i);
vis[a*1000+b*100+c*10+i]=vis[temp]+1;
}
}
}
}
return 0;
}
照题意模拟就行了 不过要确定最后上面的是s1 还是下面的是s1
(其实我觉得这题可能划分为模拟题更好一点 )
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m;
char a[maxn][maxn];
int main() {
//freopen("test","r",stdin);
//freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
cin>>T;
int kase=1;
while(T--){
cin>>n;
string s1,s2,s12;
cin>>s1>>s2>>s12;
map<string,int > mp;
mp.clear();
int ans=0;
while(1){
string temp;
for(int i=0;i<n;i++){
temp+=s2[i];
temp+=s1[i];
}
ans++;
if(temp==s12){
cout<<kase<<" "<<ans<<endl;
break;
}
else if(mp[temp]==1){
cout<<kase<<" "<<-1<<endl;
break;
}
mp[temp]=1;
s2=temp.substr(n,2*n);
s1=temp.substr(0,n);
}
kase++;
}
return 0;
}
讲道理这道题应该是这套题里最难的一道了吧。。。
首先呢这道题的前置知识有
K,M
其实这道题就是k和m的结合版 不过因为输出impossible大写了wa了一发就是了qwq
感觉我的代码写的好丑- -
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=200+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m;
struct node{
int a;
int b;
int step;
int m1;
int m2;
node *pre;
node():step(0),a(0),b(0){}
};
int A,B,C;
queue<node> q;
int main() {
freopen("test","r",stdin);
freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(cin>>A>>B>>C) {
while (q.size())
q.pop();
node a[maxn][maxn];
int ans;
for (int i = 0; i <= A; i++) {
for (int j = 0; j <= B; j++) {
a[i][j].a = i;
a[i][j].b = j;
}
}
a[0][0].pre = NULL;
q.push(a[0][0]);
int sa = INF, sb = INF;
while (q.size()) {
node temp = q.front();
q.pop();
if (temp.a == C || temp.b == C) {
cout << temp.step << endl;
ans = temp.step;
sa = temp.a;
sb = temp.b;
break;
}
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 2; j++) {
node temp1 = temp;
if (i == 1) {
if (j == 1) { // 给A倒水 i的意思几个方式
if (temp1.a < A) {
temp1.a = A;
}
} else if (j == 2) {
if (temp1.b < B) {
temp1.b = B;
}
}
}
if (i == 2) {
if (j == 1 && temp1.a) { //把1里的水倒进2里
if (temp1.a > B - temp1.b&&temp1.b<B) {
temp1.a -= B - temp1.b;
temp1.b = B;
} else {
temp1.b += temp1.a;
temp1.a = 0;
}
}
if (j == 2 && temp1.b) {
if (temp1.b > A - temp1.a&&temp1.a<A) {
temp1.b -= A - temp1.a;
temp1.a = A;
} else {
temp1.a += temp1.b;
temp1.b = 0;
}
}
}
if (i == 3) {
if (j == 1 && temp1.a) {
temp1.a = 0;
} else if (j == 2 && temp1.b) {
temp1.b = 0;
}
}
if (a[temp1.a][temp1.b].step == 0 && temp1.a >= 0 && temp1.a <= A && temp1.b >= 0 && temp1.b <= B) {
a[temp1.a][temp1.b].pre = &a[temp.a][temp.b];
a[temp1.a][temp1.b].m1 = i;
a[temp1.a][temp1.b].m2 = j;
a[temp1.a][temp1.b].step = a[temp.a][temp.b].step + 1;
q.push(a[temp1.a][temp1.b]);
}
}
}
}
if (sa != INF) {
node *head;
head = &a[sa][sb];
vector<P> v;
while (head != NULL) {
v.push_back(P(head->m1, head->m2));
head = head->pre;
if (v.size() == ans)
break;
}
for (int i = v.size() - 1; i >= 0; i--) {
if (v[i].first == 1) {
cout << "FILL(" << v[i].second << ")" << endl;
}
if (v[i].first == 2) {
if (v[i].second == 1) {
cout << "POUR(1,2)" << endl;
} else {
cout << "POUR(2,1)" << endl;
}
}
if (v[i].first == 3) {
cout << "DROP(" << v[i].second << ")" << endl;
}
}
} else {
cout << "impossible" << endl;
}
}
return 0;
}
这道题就是说给你两个人 放火 看看能不能把草放光
先用dfs求一下联通块$x$如果$x>2$则不能 其余情况均可以
但是~~
坑点在于
草不一定>=2 也有可能草=1 这样一个人点火就行了
思维定势啊 话说这个题目真的有点恶趣味233333
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
#include<algorithm>
using namespace std;
const int maxn=200+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 100000;
int T,n,m;
char a[maxn][maxn];
int vis[maxn][maxn];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int cnt;
char temp[maxn][maxn];
bool judge(int x,int y){
if(x>=0&&x<n&&y>=0&&y<m)
return true;
return false;
}
bool check(){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(a[i][j]==‘.‘)
return false;
}
}
return true;
}
void dfs(int x,int y,char c){
temp[x][y]=c;
for(int i=0;i<4;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(judge(nx,ny)&&temp[nx][ny]==‘#‘){
dfs(nx,ny,c);
}
}
}
int bfs(int sx1,int sy1,int sx2,int sy2){
queue<P> q;
memset(vis,0, sizeof(vis));
q.push(P(sx1,sy1));
q.push(P(sx2,sy2));
vis[sx1][sy1]=1;
vis[sx2][sy2]=1;
int ans=1;
while(q.size()) {
P p=q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int nx=p.first+dx[i];
int ny=p.second+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&vis[nx][ny]==0&&a[nx][ny]==‘#‘){
vis[nx][ny]=vis[p.first][p.second]+1;
ans=max(ans,vis[nx][ny]);
q.push(P(nx,ny));
}
}
}
return ans;
}
void print(){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cout<<vis[i][j];
}
cout<<endl;
}
}
int main() {
//freopen("test","r",stdin);
//freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
cin>>T;
int kase=0;
while(T--){
cin>>n>>m;
kase++;
cnt=0;
int res=INF;
vector<P> v1,v2;
for(int i=0;i<n;i++) {
for (int j = 0; j < m; j++) {
cin >> a[i][j];
}
}
memcpy(temp,a,sizeof(temp));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(temp[i][j]==‘#‘){
if(cnt==0)
dfs(i,j,‘?‘);
if(cnt==1)
dfs(i,j,‘/‘);
cnt++;
}
}
}
// print();
if(cnt>2)
cout<<"Case "<<kase<<": "<<"-1"<<endl;
else{
if(cnt==1){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(a[i][j]==‘#‘){
v1.push_back(P(i,j));
}
}
}
if(v1.size()==1){
res=0;
}
else {
for (int i = 0; i < v1.size(); i++) {
for (int j = i + 1; j < v1.size(); j++) {
res = min(res, (bfs(v1[i].first, v1[i].second, v1[j].first, v1[j].second) - 1));
}
}
}
cout<<"Case "<<kase<<": "<<res<<endl;
}else{
for(int i=0;i<n;i++) {
for (int j = 0; j < m; j++) {
if (temp[i][j] == ‘?‘)
v1.push_back(P(i, j));
if (temp[i][j] == ‘/‘)
v2.push_back(P(i, j));
}
}
for(int i=0;i<v1.size();i++){
for(int j=0;j<v2.size();j++){
res=min(res,(bfs(v1[i].first,v1[i].second,v2[j].first,v2[j].second)-1));
// print();
}
}
cout<<"Case "<<kase<<": "<<res<<endl;
}
}
}
return 0;
}
先将火烧到的时间处理一下 之后呢再处理人的位置 两次bfs 如果人到的时间<火到的时间 就将他压入队列中 要注意的是火可能有多个
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
#include<algorithm>
using namespace std;
const int maxn=2000+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 2000000;
int T,n,m;
int t[maxn][maxn];
int vis[maxn][maxn];
char a[maxn][maxn];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
queue<P> q;
int main() {
freopen("test","r",stdin);
freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
cin>>T;
while(T--){
cin>>n>>m;
int sx,sy;
bool ok=false;
while(q.size())
q.pop();
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
t[i][j]=INF;
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
vis[i][j]=0;
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>a[i][j];
if(a[i][j]==‘F‘){
q.push(P(i,j));
t[i][j]=1;
}
else if(a[i][j]==‘J‘){
sx=i;
sy=j;
}
}
}
while(q.size()){
P p=q.front();
q.pop();
for(int i=0;i<4;i++){
int nx=p.first+dx[i];
int ny=p.second+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&a[nx][ny]!=‘#‘&&t[nx][ny]==INF){
t[nx][ny]=t[p.first][p.second]+1;
q.push(P(nx,ny));
}
}
}
vis[sx][sy]=1;
q.push(P(sx,sy));
while(q.size()&&!ok){
P p=q.front();
q.pop();
if(p.first==n-1||p.first==0||p.second==m-1||p.second==0){
cout<< vis[p.first][p.second]<<endl;
ok=true;
break;
}
for(int i=0;i<4;i++){
int nx=p.first+dx[i];
int ny=p.second+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&a[nx][ny]!=‘#‘&&vis[nx][ny]==0){
vis[nx][ny]=vis[p.first][p.second]+1;
if(vis[nx][ny]<t[nx][ny]) {
q.push(P(nx, ny));
}
}
}
}
if(!ok){
cout<<"IMPOSSIBLE"<<endl;
}
}
return 0;
}
bfs追溯路径问题 我是用链表来存储路径的(其实是网上写的递归我看不懂。。)
存储一个前置节点就好啦
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m;
int a[5][5];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
struct node{
int step;
int x;
int y;
node *pre;
node():step(0){}
};
queue<node> q;
int main() {
//freopen("test","r",stdin);
//freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
node s[5][5];
while(q.size())
q.pop();
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
cin>>a[i][j];
s[i][j].x=i;
s[i][j].y=j;
}
}
s[0][0].step=1;
s[0][0].x=0;
s[0][0].y=0;
s[0][0].pre=NULL;
q.push(s[0][0]);
while(q.size()){
node temp=q.front();
q.pop();
if(temp.x==4&&temp.y==4){
break;
}
for(int i=0;i<4;i++){
int nx=temp.x+dx[i];
int ny=temp.y+dy[i];
if(nx>=0&&nx<5&&ny>=0&&ny<5&&a[nx][ny]==0&&s[nx][ny].step==0){
s[nx][ny].step=temp.step+1;
s[nx][ny].pre=&s[temp.x][temp.y];
q.push(s[nx][ny]);
}
}
}
int x=4,y=4;
node *head;
head=&s[4][4];
vector<P> v;
while(head!=NULL){
v.push_back(P(head->x,head->y));
head=head->pre;
}
for(int i=v.size()-1;i>=0;i--){
cout<<"("<<v[i].first<<", "<<v[i].second<<")"<<endl;
}
return 0;
}
没啥好说的,dfs入门水题 求联通块问题
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn = 100 + 10;
typedef pair<int, int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T, n, m;
char a[maxn][maxn];
int dx[]={-1,-1,0,1,1,1,0,-1};
int dy[]={0,1,1,1,0,-1,-1,-1};
void dfs(int x,int y){
a[x][y]=‘*‘;
for(int i=0;i<8;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&a[nx][ny]!=‘*‘){
dfs(nx,ny);
}
}
}
int main() {
//freopen("test", "r", stdin);
//freopen("out", "w", stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while (cin >> n >> m&&n+m) {
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> a[i][j];
int ans=0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++){
if(a[i][j]==‘@‘){
dfs(i,j);
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}
这个就是一个状态的问题额 设定状态一步步dfs直到为空或者到要的结果就好了哦
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,s,n,m;
struct node{
int cur[3];
};
int b[3];
int step[maxn][maxn][maxn];
queue<node> q;
int main() {
//freopen("test","r",stdin);
//freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(cin>>b[0]>>b[1]>>b[2]&&(b[0]+b[1]+b[2])){
node a;
while(q.size())
q.pop();
a.cur[0]=b[0];
a.cur[1]=0;
a.cur[2]=0;
memset(step,0, sizeof(step));
step[b[0]][0][0]=1;
q.push(a);
bool ok=false;
int half=b[0]/2;
if(b[0]%2==1)
ok=false;
else {
while (q.size()&&!ok) {
a=q.front();
q.pop();
for(int i=0;i<3;i++){
for(int j=0;j<3;j++) {
node temp = a;
if (i == j)
continue;
if((temp.cur[0]==half&&temp.cur[1]==half)||(temp.cur[1]==half&&temp.cur[2]==half)||(temp.cur[0]==half&&temp.cur[2]==half)){
ok=true;
cout<<step[temp.cur[0]][temp.cur[1]][temp.cur[2]]-1<<endl;
i=5;
break;
}
if (temp.cur[i] > 0) {
if (temp.cur[i] >= b[j] - temp.cur[j]) {
temp.cur[i]-= b[j] - temp.cur[j];
temp.cur[j]=b[j];
}else{
temp.cur[j]+=temp.cur[i];
temp.cur[i]=0;
}
}
if(step[temp.cur[0]][temp.cur[1]][temp.cur[2]]==0){
step[temp.cur[0]][temp.cur[1]][temp.cur[2]]=step[a.cur[0]][a.cur[1]][a.cur[2]]+1;
q.push(temp);
}
}
}
}
}
if(!ok){
cout<<"NO"<<endl;
}
}
return 0;
}
一开始想的是每一个$@$也就是kfc bfs一下 但是T了qwq
后来想了想两次bfs就好了 然后去每个kfc的最小值喵
/*
author:hdsdogge
begin:
end:
cost:
*/
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
#include<algorithm>
using namespace std;
const int maxn=200+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000;
int T,n,m;
char a[maxn][maxn];
int vis[maxn][maxn][2];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int bfs1(int sx,int sy){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
vis[i][j][0]=INF;
}
}
queue<P> q;
q.push(P(sx,sy));
vis[sx][sy][0]=0;
while(q.size()){
P p=q.front();
q.pop();
for(int i=0;i<4;i++){
P temp=p;
int nx=temp.first+dx[i];
int ny=temp.second+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&(a[nx][ny]==‘@‘||a[nx][ny]==‘.‘)&&vis[nx][ny][0]==INF){
vis[nx][ny][0]=vis[p.first][p.second][0]+1;
q.push(P(nx,ny));
}
}
}
}
int bfs2(int sx,int sy){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
vis[i][j][1]=INF;
}
}
queue<P> q;
q.push(P(sx,sy));
vis[sx][sy][1]=0;
while(q.size()){
P p=q.front();
q.pop();
for(int i=0;i<4;i++){
P temp=p;
int nx=temp.first+dx[i];
int ny=temp.second+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&(a[nx][ny]==‘@‘||a[nx][ny]==‘.‘)&&vis[nx][ny][1]==INF){
vis[nx][ny][1]=vis[p.first][p.second][1]+1;
q.push(P(nx,ny));
}
}
}
}
int main() {
//freopen("test","r",stdin);
//freopen("out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(cin>>n>>m){
int ans=INF;
int sx,sy,ex,ey;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>a[i][j];
if(a[i][j]==‘Y‘){
sx=i;
sy=j;
}
else if(a[i][j]==‘M‘){
ex=i;
ey=j;
}
}
}
bfs1(sx,sy);
bfs2(ex,ey);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(a[i][j]==‘@‘) {
ans = min(vis[i][j][0]+vis[i][j][1], ans);
}
}
}
cout<<ans*11<<endl;
}
return 0;
}
标签:i++ 前置 -- cost continue 简单搜索 memset pat flag
原文地址:https://www.cnblogs.com/hdsdogge/p/9403858.html