美文网首页
数据结构

数据结构

作者: 云中翻月 | 来源:发表于2019-06-07 19:45 被阅读0次

    优先队列

    POJ 3614: Sunscreen
    题解链接 https://www.jianshu.com/p/dfb78e06c19d
    代码如下

    /*
    
    */
    #define method_1
    #ifdef method_1
    /*
    
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    typedef long long ll;
    const int maxn=2500+5;
    const int INF=0x3f3f3f3f;
    int c,l;
    struct node{
        int x,y;
    }p[maxn],q[maxn]; 
    int ans=0;
    bool operator<(const node &a,const node &b){
        return a.x>b.x;
    }
    int main() {
        ios::sync_with_stdio(false);
        //freopen("Sunscreen.in","r",stdin);
        cin>>c>>l;
        for(int i=1;i<=c;i++){
            cin>>p[i].x>>p[i].y; 
        }
        for(int i=1;i<=l;i++){
            cin>>q[i].x>>q[i].y;
        }
        sort(p+1,p+c+1);
    //  for(int i=1;i<=c;i++){
    //      cout<<p[i].x<<endl;
    //  }
        for(int i=1;i<=c;i++){
            int temp=-1,id=-1;
            for(int j=1;j<=l;j++){
                if(q[j].y>0&&(p[i].x<=q[j].x)&&(p[i].y>=q[j].x)){
                    if(q[j].x>temp){
                        temp=q[j].x;
                        id=j;
                    }
                }
            }
            if(temp!=-1){
                ans++;
                q[id].y--;
            }
        }
        cout<<ans;
        return 0;
    }
    #endif
    #ifdef method_2
    /*
    
    */
    
    #endif
    #ifdef method_3
    /*
    
    */
    
    #endif
    

    POJ 2010: Moo University - Financial Aid
    将所有奶牛按照score升序排序后,从大向小一次尝试作为中位数是否可行即可。
    为了提高对于每头奶牛判断的效率,用sum1[i]表示i左侧c/2头牛的最小aid和,可用一个大小固定为n/2的大根堆来求,每次与堆顶元素比较。
    同理可以对称的定义sum2[i]。
    代码如下

    /*
    
    */
    #define method_1
    #ifdef method_1
    /*
    将所有奶牛按照score升序排序后,从大向小一次尝试作为中位数是否可行即可。
    为了提高对于每头奶牛判断的效率,用sum1[i]表示i左侧c/2头牛的最小aid和,可用一个大小固定为n/2的大根堆来求,每次与堆顶元素比较。
    同理可以对称的定义sum2[i]。 
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iomanip>
    #include<ctime>
    #include<string>
    #define D(x) cout<<#x<<" = "<<x<<"  "
    #define E cout<<endl
    using namespace std;
    typedef long long ll;
    typedef pair<int,int>pii;
    const int maxn=100000+5;
    const int INF=0x3f3f3f3f;
    int n,c,f,sum1[maxn],sum2[maxn];//sum1[i]表示i左侧c/2头牛的最小aid和 用一个大小固定为n/2的大根堆来求 每次与堆顶元素比较 
    struct node{
        int s,aid;
        bool operator<(const node& h)const{return s<h.s;}
    }cow[maxn];
    priority_queue<int>q;
    void pre1(){ 
        while(q.size()) q.pop();
        int sum=0,nowf; //堆中所有元素和 
        for(int i=1;i<=c;i++){
            sum1[i]=sum;
            if(q.size()) nowf=q.top();
            if(q.size()<n/2){
                q.push(cow[i].aid);
                sum+=cow[i].aid;
            }
            else{
                if(cow[i].aid<nowf){
                    q.pop();
                    q.push(cow[i].aid);
                    sum=sum-nowf+cow[i].aid;
                }
            }
    //      D(sum1[i]);
        }
    }
    void pre2(){
        while(q.size()) q.pop();
        int sum=0,nowf; //堆中所有元素和 
        for(int i=c;i>=1;i--){
            sum2[i]=sum;
            if(q.size()) nowf=q.top();
            if(q.size()<n/2){
                q.push(cow[i].aid);
                sum+=cow[i].aid;
            }
            else{
                if(cow[i].aid<nowf){
                    q.pop();
                    q.push(cow[i].aid);
                    sum=sum-nowf+cow[i].aid;
                }
            }
    //      D(sum2[i]);
        }
    }
    int main() {
    //  ios::sync_with_stdio(false);
        //freopen("Moo University - Financial Aid.in","r",stdin);
        scanf("%d%d%d",&n,&c,&f);
        for(int i=1;i<=c;i++) scanf("%d%d",&cow[i].s,&cow[i].aid);
        sort(cow+1,cow+c+1);
        pre1();
        pre2();
        bool flag=false; 
        for(int i=c-n/2;i>=n/2+1;i--){ //从大到小依次枚举当前值能否作为中位数 
            if(cow[i].aid+sum1[i]+sum2[i]<=f){
                flag=true;
                cout<<cow[i].s;
                break;
            }
        }
        if(flag==false) cout<<-1;
        return 0;
    }
    #endif
    #ifdef method_2
    /*
    
    */
    
    #endif
    #ifdef method_3
    /*
    
    */
    
    #endif
    

    并查集

    POJ 2236: Wireless Network
    这题的复杂度是O(N ^ 2 + M),因为修理操作最多执行N次。
    每次检测N - 1个计算机,剩下的只能是判断操作,每一次判断可以看作O(1)。
    代码如下

    /*
    
    */
    #define method_1
    #ifdef method_1
    /*
    这题的复杂度是O(N ^ 2 + M),因为修理操作最多执行N次。 
    每次检测N - 1个计算机,剩下的只能是判断操作,每一次判断可以看作O(1)。 
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iomanip>
    #include<ctime>
    #include<string>
    #define D(x) cout<<#x<<" = "<<x<<"  "
    #define E cout<<endl
    using namespace std;
    typedef long long ll;
    typedef pair<int,int>pii;
    const int maxn=1000+5;
    const int INF=0x3f3f3f3f;
    const string s1="SUCCESS";
    const string s2="FAIL";
    int f[maxn],n,d,x[maxn],y[maxn],vis[maxn]={0};
    void init(){
        for(int i=1;i<=n;i++) f[i]=i;
    }
    int find(int x){
        return f[x]==x?x:f[x]=find(f[x]);
    }
    bool check(int i,int j){ //判断i和j两个电脑能否直接连接 
        int dis=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
        return dis<=d*d;
    }
    int main() {
    //  ios::sync_with_stdio(false);
        //freopen("Wireless Network.in","r",stdin);
        scanf("%d%d",&n,&d);
        init();
        for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
        getchar();
        int p,q;
        char op;
        while(~scanf("%c",&op)){
    //      cout<<op<<endl;
            if(op=='O'){
                scanf("%d",&p);
                if(vis[p]) continue;
                vis[p]=1;
                int fp=find(p);
                for(int i=1;i<=n;i++){
                    if(i==p) continue;
                    if(vis[i]&&check(p,i)){
                        int fi=find(i);
                        f[fi]=fp;
                    }
                }
            }
            else{
                scanf("%d%d",&p,&q);
                if(find(p)==find(q)) printf("%s\n",s1.c_str());
                else printf("%s\n",s2.c_str());
            }
            getchar();
        }
        return 0;
    }
    #endif
    #ifdef method_2
    /*
    
    */
    
    #endif
    #ifdef method_3
    /*
    
    */
    
    #endif
    

    POJ 1703: Find them, Catch them
    拓展域并查集模板题。
    375msAC。
    用cin会超时。
    代码如下

    /*
    
    */
    #define method_1
    #ifdef method_1
    /*
    拓展域并查集模板题。 
    375msAC。 
    用cin会超时。 
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iomanip>
    #include<ctime>
    #include<string>
    #define D(x) cout<<#x<<" = "<<x<<"  "
    #define E cout<<endl
    using namespace std;
    typedef long long ll;
    typedef pair<int,int>pii;
    const int maxn=2e5+5;
    const int INF=0x3f3f3f3f;
    const string s1="Not sure yet.";
    const string s2="In different gangs.";
    const string s3="In the same gang.";
    int n,m,T,f[maxn];
    void init() {
        for(int i=1; i<=2*n; i++) f[i]=i;
    }
    int find(int x) {
        return f[x]==x?x:f[x]=find(f[x]);
    }
    int main() {
    //  ios::sync_with_stdio(false);
        //freopen("Find them, Catch them.in","r",stdin);
    //  cin>>T;
        scanf("%d",&T);
        while(T--) {
            scanf("%d%d",&n,&m);
    //      cin>>n>>m;
            init();
            char op;
            int x,y;
            while(m--) {
                getchar(); //读入换行符 
    //          cin>>op>>x>>y;
                scanf("%c%d%d",&op,&x,&y);
    //          cout<<x<<" "<<y<<endl;
                int x1=find(x),y1=find(y),x2=find(x+n),y2=find(y+n);
                if(op=='A') {
                    /*
                    if(x1==y1) cout<<s3<<endl;
                    else if(x1==y2) cout<<s2<<endl;
                    else cout<<s1<<endl;
                    */
                    if(x1==y1) printf("%s\n",s3.c_str());
                    else if(x1==y2) printf("%s\n",s2.c_str());
                    else printf("%s\n",s1.c_str());//printf不能直接输出string 
                } else {
                    f[x1]=y2,f[x2]=y1;
                }
            }
        }
        return 0;
    }
    #endif
    #ifdef method_2
    /*
    
    */
    
    #endif
    #ifdef method_3
    /*
    
    */
    
    #endif
    

    相关文章

      网友评论

          本文标题:数据结构

          本文链接:https://www.haomeiwen.com/subject/frxdxctx.html