深搜-4

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;
}
邮局
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值