先说10.2的F题,当时看着像动态规划就做另外的题了,现在看了看别人的思路感觉设计的好巧妙,思路是先用一个结构体存输入顺序和输入的数据还有一个记录答案,用贪心的方法,找现在已经度过的天数中用时最早的那个,然后判断现在的时间和最早的时间是否间隔超过m如果超过就把那天的时间换成现在的,(这个可以用优先队列实现)如果不超过,天数就加一天,在把现在的时间放进队列,记录答案就可以。代码:

#include<bits/stdc++.h>
using namespace std;
struct mp
{
    int num;
    int id;
    int ans;
    friend bool operator<(const mp p1,const mp p2)
    {
        return p1.num >p2.num;
    }
}o;
vector<mp>p;
bool cmp1(mp p1,mp p2)
{
    return p1.num <p2.num ;
}
bool cmp2(mp p1,mp p2)
{
    return p1.id <p2.id ;
}
int main()
{
    int n,m,d;
    cin>>n>>m>>d;
    for(int i=0;i<n;i++)
    {
        int v;
        cin>>v;
        o.id =i;
        o.num=v;
        p.push_back(o);
     } 
     priority_queue<mp>q;
     sort(p.begin(),p.end(),cmp1);
     p[0].ans=1;
     q.push(p[0]);
     int t=1;
     for(int i=1;i<n;i++)
     {
         o=q.top();
         if(p[i].num>o.num +d)
         {
             p[i].ans=o.ans;
             q.pop();
         }
         else
         {
             t++;
             p[i].ans=t;
         }
         q.push(p[i]);
     }
     sort(p.begin(),p.end(),cmp2);
     cout<<t<<endl;
     for(int i=0;i<n;i++)
     {
         cout<<p[i].ans<<" ";
     }
}
View Code

再说10.3的排座位和社交集群,这两题就是裸的并查集(然而我连并查集都出错...)并查集判断是否在同一个集里是用find找而不是直接用原数组(重要的事要说三遍,但是我懒得打了..)代码:

排座位

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int s[1005],v[1020][1020];
int findf(int x)
{
    return (x==s[x])?x:findf(s[x]);
}
void unif(int x,int y)
{
    x=findf(x);
    y=findf(y);
    if(x!=y)s[y]=x;
}
int main()
{
    for(int i=0;i<1003;i++)
    {
        s[i]=i;
    }
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
         if(c==1)
         {
             unif(a,b);
         //    cout<<s[a]<<" "<<s[b]<<endl;
         }
         else
         {
             v[a][b]=1;
             v[b][a]=1;
         }
    }
    //for(int i=0;i<10;i++)cout<<s[i]<<" ";
    for(int i=0;i<k;i++)
    {
        int a,b;
        cin>>a>>b;
    //    cout<<s[a]<<" "<<s[b]<<endl;
        if(findf(s[a])==findf(s[b])&&v[a][b]==0)cout<<"No problem"<<endl;
        if(findf(s[a])!=findf(s[b])&&v[a][b]==0)cout<<"OK"<<endl;
        if(findf(s[a])==findf(s[b])&&v[a][b]==1)cout<<"OK but..."<<endl;
        if(findf(s[a])!=findf(s[b])&&v[a][b]==1)cout<<"No way"<<endl;
    }
}
View Code

社交集群

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int s[1005];
int findf(int x)
{
    return (x==s[x])?x:findf(s[x]);
}
void unif(int x,int y)
{
    x=findf(x);
    y=findf(y);
    if(x!=y)s[y]=s[x];
}
bool cmp(int a,int b)
{
    return a>b;
}
int a[1005];
vector<int>p[1005];
int main()
{
    int t;
    cin>>t;
    for(int i=0;i<=t;i++)
    {
        s[i]=i;
        
    }
    for(int i=1;i<=t;i++)
    {
        int n;
        scanf("%d:",&n);
        for(int j=0;j<n;j++)
        {
            int v;
            cin>>v;
            p[v].push_back(i);
        }
    }
    for(int i=0;i<=1000;i++)
    {
        if(p[i].size()==0)continue;
    //    cout<<p[i].size()<<endl;
        for(int j=0;j<p[i].size()-1;j++)
        {
        //    cout<<p[i][j]<<" ";
            unif(p[i][j],p[i][j+1]);
        //    cout<<s[p[i][j]]<<" "<<s[p[i][j+1]]<<" ";
        }
    //    cout<<endl;
    }
    for(int i=1;i<=t;i++)
    {
    //    cout<<s[i]<<endl;
        a[findf(s[i])]++;
    }
    vector<int>q;
    q.clear();
    for(int i=0;i<=t;i++)
    {
        if(a[i]>0)q.push_back(a[i]);
    }
    sort(q.begin(),q.end(),cmp);
    cout<<q.size()<<endl;
    cout<<q[0];
    for(int i=1;i<q.size();i++)
    {
        cout<<" "<<q[i];
    }
}
View Code

重排链表,emm,怎么说呢,也算是没认真看题吧,忽略了有多余的节点这种情况,改完就可以了。代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
struct mp
{
    int addres;
    int data;
    int next;
    int rank;
}o[1000005];
bool cmp(mp p1,mp p2)
{
    return p1.rank<p2.rank;
 } 
int main()
{
    int num,n;
    cin>>num>>n;
    vector<mp>p;
    p.clear();
    for(int i=0;i<n;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        o[a].addres =a;
        o[a].data =b;
        o[a].next =c;
     } 

     int cnt=0;
     for(;num!=-1;num=o[num].next)
     {
         cnt++;
         o[num].rank=cnt;
         p.push_back(o[num]);
     }
     sort(p.begin(),p.end(),cmp);
     n=cnt;
     cnt=0;
     num=n-1;
     while(1)
     {
     //    cout<<num<<endl;
         if(num>(n-1)/2)
         {
             if(cnt==n-1)printf("%05d %d -1\n",p[num].addres,p[num].data);
             else printf("%05d %d %05d\n",p[num].addres,p[num].data,p[n-1-num].addres);
             num=n-1-num;
         }    
         else
         {
             if(cnt==n-1)printf("%05d %d -1\n",p[num].addres,p[num].data);
             else printf("%05d %d %05d\n",p[num].addres,p[num].data,p[n-1-num-1].addres);
             num=n-1-num-1;
         }
         cnt++;
         if(cnt>=n)break;
     }
}
View Code

垃圾箱分类,这题看起来很麻烦(也确实挺麻烦)当时就没做,大体思路就是找所有居民到所有垃圾箱的最短路,如果在某一个垃圾箱有一个最短距离大于给的值就不能作为站点,其他的都成立,在成立的里面找最短距离最小,不然就平均距离最小,不然就id最小,存图也是个小麻烦事,十个垃圾站,存1到10,居民点就在存+10,然后在用Dijktra算法求出每个垃圾站是否满足条件,满足条件就存到数组里,最后在对数组排序,判断数组长度就可以了。(这题样例是向上取整,但是我样例没过,其他的都对了,%.1f好像是向下取整...)代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int n,m,k,ds;
struct mp
{
    int  minn;
    int pre;
    int idd;
}o;
vector<mp>anss;
bool cmp(mp p1,mp p2)
{
    if(p1.minn==p2.minn )
    {
        if(p1.pre ==p2.pre )
        {
            return p1.idd<p2.idd ;
        }
        return p1.pre <p2.pre ;
    }
    return p1.minn >p2.minn ;
}
struct edge
{
    int from,to,w;
    edge(int a,int b,int c)
    {
        from=a;
        to=b;w=c;
    }
};
vector<edge>e[10050];
struct node
{
    int id,dis;
    node(int a,int b)
    {
        id=a;dis=b;
    }
    bool operator <(const node a)const
    {
        return dis>a.dis;
    }
};
int change(string s)
{
    int o=0;
    int i;
    if(s[0]=='G')i=1;
    else i=0;
    //cout<<s<<" "<<i<<endl;
    for(;i<s.size();i++)
    {
        o=o*10+s[i]-'0';
    }
    if(s[0]!='G')o=o+10;
    return o;
}
void dijktra(int s)
{
    int len[10050];
    bool done[10055];
    for(int i=0;i<=n+11;i++)
    {
        len[i]=0x3f3f3f3f,done[i]=false;
    }
    len[s]=0;
    priority_queue<node>q;
    q.push(node(s,len[s]));
    while(!q.empty())
    {
        node u=q.top();
        q.pop();
        if(done[u.id])
            continue;
        done[u.id]=true;
        for(int i=0;i<e[u.id].size();i++)
        {
            edge y=e[u.id][i];
            if(len[y.to ]>y.w+u.dis)
            {
                len[y.to]=y.w+u.dis;
                q.push(node(y.to,len[y.to ]));
            }
        }
    }
    double min=0x3f3f3f3f,ans=0;
    int flag=0;
    
    for(int i=11;i<=n+10;i++)
    {
        if(len[i]<min)min=len[i];
        ans+=len[i];
        if(len[i]>ds)flag=1;
    //if(s==3)cout<<len[i]<<" "<<flag<<endl;
    }
    if(flag==0)
    {
        o.minn=min;
        o.pre =ans;
        o.idd=s;
        anss.push_back(o);
    //    if(s==1)cout<<o.minn<<" "<<o.pre*1.0/(double)n<<endl;
    }
}

int main()
{
    anss.clear();
    cin>>n>>m>>k>>ds;
    for(int i=0;i<k;i++)
    {
        string a,b;
        int len;
        cin>>a>>b>>len;
    //    cout<<a<<" "<<b<<" "<<len<<endl;
        int vv,bb;
        vv=change(a);
        bb=change(b);
    //    cout<<vv<<" "<<bb<<endl;
        e[vv].push_back(edge(vv,bb,len));
        e[bb].push_back(edge(bb,vv,len));
    }
    for(int i=1;i<=m;i++)
    {
        dijktra(i);
    }
    sort(anss.begin(),anss.end(),cmp);
    if(anss.size()==0)cout<<"No Solution"<<endl;
    else
    {
        printf("G%d\n",anss[0].idd);
        printf("%.1lf %.1lf\n",anss[0].minn*1.0,anss[0].pre*1.0/(double)n);
    }
}
View Code

 

posted on 2020-10-06 20:41  小灰灰的父亲  阅读(91)  评论(0)    收藏  举报