1.传数组问题,指向的是同一空间。递归传数组时,在这一层开个临时数组然后传,下一层就能访问这个临时数组了。定义一个数组,然后传,不开临时数组,,相当于没传。
2.递归终止条件控制问题。
3.回溯问题。
#include<bits/stdc++.h>
using namespace std;
const int N=1e3;
struct node
{
int x,y;
}a[100],b[100];
int n,m,k;
int vis[100],vis1[100];
double ans;
double dis(node p,node q)
{
return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}
void dfs(int pos,int num)
{
if(pos>m) return;
if(num==k)
{
double s=0;
for(int i=0;i<n;i++)
{
double minn=999999;
for(int j=0;j<m;j++)
{
if(vis[j]&&dis(a[i],b[j])<minn)
{
minn=dis(a[i],b[j]);
}
}
s+=minn;
}
// for(int i=0;i<m;i++)
// {
// if(vis[i]) printf("%d ",i);
// }cout<<endl;printf("minn=%lf\n",s);
if(s<ans)
{
ans=s;
for(int i=0;i<m;i++)
{
vis1[i]=vis[i];
}
}
//printf("s=%lf num=%d\n",s,num);
return ;
}
vis[pos]=1;dfs(pos+1,num+1);
vis[pos]=0;dfs(pos+1,num);
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&b[i].x,&b[i].y);
}
ans=999999999;
dfs(0,0);
//printf("%lf\n",ans);
for(int i=0;i<m;i++)
{
if(vis1[i]) printf("%d ",i+1);
}
}
return 0;
}//第一遍手打暴力来遍-50
#include<bits/stdc++.h>//终止条件控制问题
#define inf 999999
using namespace std;
const int N=1e3;
struct node
{
int x,y;
}a[100],b[100];
int n,m,k;
int vis[100],vis1[100];
double diss[100][100],c[100];
double ans;
double dis(node p,node q)
{
return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}
void dfs(int pos,int num,double s,double *t)
{
//if(pos>m) return;/*放上面(第pos个位置填到m-1,m就不能填了,但下面的判断num==k需要到m步才会处理)一直没想到原因,,丫丫*/
if(num>k) return;
if(num==k)
{ //printf("%lf %d ",s,pos);
//for(int i=0;i<m;i++) if(vis[i]) printf("%d ",i);printf("s=%lf\n",s);
//for(int i=0;i<n;i++) printf("%lf ",t[i]);cout<<endl;
if(s<ans)
{
ans=s;
for(int i=0;i<m;i++)
{
vis1[i]=vis[i];//printf("%d ",vis[i]);
}//cout<<endl;
}
return ;
}
if(pos>=m) return;/*放下面,分析清楚了原因,就知道如何控制了,,下次就不乱放,找种做模板思维*/
vis[pos]=1;
double pp[55],ss=s;
//cout<<"pos="<<pos<<" ";for(int i=0;i<n;i++) printf("%lf ",t[i]);cout<<endl;
for(int i=0;i<n;i++)
{
pp[i]=t[i];
if(diss[i][pos]<pp[i])
{
ss=ss-pp[i]+diss[i][pos];
pp[i]=diss[i][pos];
}
//ss+=pp[i];
}//printf("ss=%lf\n",ss);
//for(int i=0;i<n;i++) printf("%lf ",pp[i]);cout<<endl;
dfs(pos+1,num+1,ss,pp);
vis[pos]=0;dfs(pos+1,num,s,t);
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&b[i].x,&b[i].y);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
diss[i][j]=dis(a[i],b[j]);//printf("%lf ",diss[i][j]);
}//cout<<endl;
}
for(int i=0;i<n;i++) c[i]=inf;
ans=999999999;
dfs(0,0,inf*n,c);
//printf("%lf\n",ans);
for(int i=0;i<m;i++)
{
if(vis1[i]) printf("%d ",i+1);
}
}
return 0;
}//-80/*感觉是换了方法,改用传数组写*/
#include<bits/stdc++.h>//加判断
#define inf 999999
using namespace std;
const int N=1e3;
struct node
{
int x,y;
}a[100],b[100];
int n,m,k;
int vis[100],vis1[100];
double diss[100][100],c[100];
double ans;
double dis(node p,node q)
{
return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}
void dfs(int pos,int num,double s,double *t)
{
if(k-num>m-pos) return;/*看后面的数量够不够*/
if(num==k)
{
if(s<ans)
{
ans=s;
for(int i=0;i<m;i++)
{
vis1[i]=vis[i];
}
}
return ;
}
//if(pos>=m) return;
double pp[55],ss=s;
//cout<<"pos="<<pos<<" ";for(int i=0;i<n;i++) printf("%lf ",t[i]);cout<<endl;
int flag=0;
for(int i=0;i<n;i++)
{
pp[i]=t[i];
if(diss[i][pos]<pp[i])
{
flag=1;
ss=ss-pp[i]+diss[i][pos];
pp[i]=diss[i][pos];
}
}
//for(int i=0;i<n;i++) printf("%lf ",pp[i]);cout<<endl;
if(flag) {vis[pos]=1;dfs(pos+1,num+1,ss,pp);} /*加了判断是否选这个邮局*/
vis[pos]=0;dfs(pos+1,num,s,t);
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&b[i].x,&b[i].y);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
diss[i][j]=dis(a[i],b[j]);//printf("%lf ",diss[i][j]);
}//cout<<endl;
}
for(int i=0;i<n;i++) c[i]=inf;
ans=999999999;
dfs(0,0,inf*n,c);
for(int i=0;i<m;i++)
{
if(vis1[i]) printf("%d ",i+1);
}
}
return 0;
}-90/*加了些判断,但最后点超时,丫丫*/
#include<bits/stdc++.h>//问题点。。//感觉传数组耗时间更多了,,每次都要传n大小的数组。。找到方案后再n*m记录结果肯定超时,C10/25*n*m超。
using namespace std;
const int N=1e3;
typedef long long ll;
struct node
{
int x,y;
}a[100],b[100];
int n,m,k;
int vis[100],vis1[100];
double ans;
double dis(node p,node q)
{
return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}
void dfs(int pos,int num)
{
if(pos>m) return;
if(num==k)
{
double s=0;
for(int i=0;i<n;i++)
{
double minn=999999;
for(int j=0;j<m;j++)
{
if(vis[j]&&dis(a[i],b[j])<minn)
{
minn=dis(a[i],b[j]);
}
}
s+=minn;
}
if(s<ans)
{
ans=s;
for(int i=0;i<m;i++)
{
vis1[i]=vis[i];
}
}
//printf("s=%lf num=%d\n",s,num);
return ;
}
vis[pos]=1;dfs(pos+1,num+1);
vis[pos]=0;dfs(pos+1,num);
}
int main()
{
//ll s=1;
//for(int i=1;i<=25;i++) s*=2;cout<<s<<endl;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&b[i].x,&b[i].y);
}
ans=999999999;
int book[100];
memset(book,0,sizeof(book));
for(int i=0;i<n;i++)
{
double minn=99999;int l=0;
for(int j=0;j<m;j++)
{
if(dis(a[i],b[j])<minn)
{
minn=dis(a[i],b[j]);
l=j;
}
}
book[l]=1;
}
int num=0;
for(int i=0;i<m;i++)
{
if(book[i]){b[num].x=b[i].x,b[num++].y=b[i].y;}
} m=num;
dfs(0,0);
for(int i=0;i<m;i++)
{
if(vis1[i]) printf("%d ",i+1);
}
}
return 0;
}/*有问题的贪心*/
#include<bits/stdc++.h>//回溯错误 偶然换位置发现的错误
#define inf 999999
using namespace std;
const int N=1e3;
struct node
{
int x,y;
}a[100],b[100];
int n,m,k;
int vis[30],vis1[30];
double diss[100][100],c[100];
double ans;
double dis(node p,node q)
{
return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}
void dfs(int pos,int num,double s,double *t)
{
if(pos>m||k-num>m-pos) return;/**/
if(num==k)
{
if(s<ans)
{
ans=s;
// for(int i=0;i<m;i++)
{
//vis1[i]=vis[i];
memcpy(vis1,vis,sizeof(vis));
}
}
return ;
}
//if(pos>=m) return;
double pp[55],ss=s;
//cout<<"pos="<<pos<<" ";for(int i=0;i<n;i++) printf("%lf ",t[i]);cout<<endl;
int flag=0;
for(int i=0;i<n;i++)
{
pp[i]=t[i];
if(diss[i][pos]<pp[i])
{
flag=1;
ss=ss-pp[i]+diss[i][pos];
pp[i]=diss[i][pos];
}
}
//for(int i=0;i<n;i++) printf("%lf ",pp[i]);cout<<endl;
/*vis[pos]=0;dfs(pos+1,num,s,t);
if(flag) {vis[pos]=1;dfs(pos+1,num+1,ss,pp);vis[pos]=0;}*/ //--回溯的体现。后面的回溯竟忘了,变-40,深搜思想不深刻呀。后来改用这种,神奇错了,改过。
/*if(flag){vis[pos]=1;dfs(pos+1,num+1,ss,pp);}vis[pos]=0;dfs(pos+1,num,s,t);*/ //这样写开始理解为选标记为1,不选标记为0;是那么一回事,同时vis[pos]=0,也是回溯。开始写的这种。
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&b[i].x,&b[i].y);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
diss[i][j]=dis(a[i],b[j]);//printf("%lf ",diss[i][j]);
}//cout<<endl;
}
for(int i=0;i<n;i++) c[i]=inf;
ans=999999999;
dfs(0,0,inf*n,c);
for(int i=0;i<m;i++)
{
if(vis1[i]) printf("%d ",i+1);
}
}
return 0;
}
邮局