3-9-1 dfs
水仙花数进阶版,如果正常遍历区间数字的话,由于n<=19数据规模很大,肯定超时,所以可以用dfs搜索数字出现的次数合理化路径并轻剪枝,具体操作是每一次选择搜索都有n种选择,每种选择都代表对应层数数字的出现次数,可以用树的结构来更好的理解
最左边的层数代表可能出现在最后结果中每一位上0-9的数字,数的节点代表每个数字可能出现的次数,如上图是以n=2示例的,搜索的时候只需要边深入边记录数字即可,由于这种搜索有重复性和无序性,采用set来存最后的结果
#include<iostream>
#include<math.h>
#include<set>
#include<time.h>
using namespace std;
typedef long long LL;
LL n;
set<LL>res;
LL p[10];
bool is_num(LL num){
LL t=num;
LL sum=0,cntt=0;
while(t){
sum+=p[t%10];
t/=10;
cntt++;
}
if(sum==num&&cntt==n)
return true;
return false;
}
void dfs(LL level,LL level_pow_sum,LL totaln){
if(level>9){
return ;
}
if(totaln>n){
return ;
}
else{
if(is_num(level_pow_sum))
res.insert(level_pow_sum);
for(LL t=0;t<=n;t++){
totaln+=t;
if(totaln>n)
break;
level_pow_sum+=p[level+1]*t;
dfs(level+1,level_pow_sum,totaln);
totaln-=t;
level_pow_sum-=p[level+1]*t;
}
}
}
int main(){
clock_t s,e;
s=clock();
ios::sync_with_stdio(false);
cin>>n;
for(LL i=0;i<10;i++){
p[i]=pow(i,n);
}
dfs(0,p[0],0);
set<LL>::iterator it;
for(it=res.begin();it!=res.end();it++){
cout<<*it<<endl;
}
e=clock();
cout<<double(e-s)/CLOCKS_PER_SEC;
return 0;
}
3-9-2 bfs
这题dfs和bfs都可以,注意一些特殊情况:如果起点或者终点为0,那么一定不可以翻转,另外如果起点和终点重叠或者棋子不一样,也不能翻转
#include<iostream>
#include<queue>
using namespace std;
const int maxn=1005;
const int INF=0x3f3f3f3f;
int map[maxn][maxn],min_step[maxn][maxn];
int n,m;
struct node{
int x,y;
int direction=INF;
int step=0;
};
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
bool bfs(int x1,int y1,int x2,int y2){
queue<node>q;
fill(min_step[0],min_step[0]+maxn*maxn,INF);
node s,t,tt;
if(!map[x1][y1]||!map[x2][y2]||map[x1][y1]!=map[x2][y2]){
return false;
}
s.x=x1,s.y=y1;
q.push(s);
while(!q.empty()){
t=q.front();
q.pop();
for(int i=0;i<4;i++){
tt=t;
tt.x+=dir[i][0],tt.y+=dir[i][1];
if(tt.x>=1&&tt.x<=n&&tt.y>=1&&tt.y<=m&&(!map[tt.x][tt.y]||(tt.x==x2&&tt.y==y2))){
if(tt.direction!=INF){
if(tt.direction!=i){
tt.direction=i;
tt.step++;
}
}else{
tt.direction=i;
}
if(tt.step>2)continue;
if(tt.step<=min_step[tt.x][tt.y]){
min_step[tt.x][tt.y]=tt.step;
if(tt.x==x2&&tt.y==y2&&tt.step<=2)
return true;
q.push(tt);
}
}
}
}
return false;
}
int main(){
ios::sync_with_stdio(false);
while(cin>>n>>m&&(n||m)){
fill(map[0],map[0]+maxn*maxn,0);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>map[i][j];
}
}
int t;
cin>>t;
while(t--){
int a,b,c,d;
cin>>a>>b>>c>>d;
if(bfs(a,b,c,d)){
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
}
}
return 0;
}