The 36th ACM/ICPC Asia Regional Dalian Site —— Online Contest(套题HDU4001-4010)

来源:互联网 发布:招聘游戏程序员 编辑:程序博客网 时间:2024/05/23 20:55

HDU4001:To Miss Our Children Time

题意:堆积木,积木有4个参数,分别为长,宽,高,要求。要求有三种,一种是在上面的积木的长和宽要大于等于下面接触的,第二种是上面的积木长和宽要大于等于下面接触的,但是面积不能相同,第三种就是上面的积木的长和宽要大于下面接触的。一共有n个积木,问最多能堆多高。

思路:简单DP。

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <string>#include <algorithm>#include <queue>#include <cmath>using namespace std;typedef long long ll;const int maxn = 1000+10;struct block{    int a,b,c,d;    block(int a,int b,int c,int d):a(a),b(b),c(c),d(d){}};vector<block> vb;int n;ll dp[maxn];ll dfs(int x){    if(dp[x] != -1) return dp[x];    ll ans = vb[x].c;    for(int i = 0; i < n; i++){        if(i==x) continue;        if(vb[x].d==0){            if(vb[i].a <= vb[x].a && vb[i].b <= vb[x].b){                ans = max(ans,dfs(i)+vb[x].c);            }        }else if(vb[x].d ==1){            if((vb[i].a <= vb[x].a && vb[i].b < vb[x].b )|| (vb[i].a < vb[x].a && vb[i].b <= vb[x].b) ){                ans = max(dfs(i)+vb[x].c,ans);            }        }else{            if(vb[i].a < vb[x].a && vb[i].b < vb[x].b){                ans = max(ans,dfs(i)+vb[x].c);            }        }    }    return dp[x] = ans;}int main(){    while(~scanf("%d",&n) && n){        vb.clear();        memset(dp,-1,sizeof dp);        for(int i = 0; i < n; i++){            int a,b,c,d;            scanf("%d%d%d%d",&a,&b,&c,&d);            if(a > b) swap(a,b);            vb.push_back(block(a,b,c,d));        }        ll ans = 0;        for(int i = 0; i < n; i++){            ans = max(ans,dfs(i));        }        cout<<ans<<endl;    }    return 0;}


HDU4002:Find the maximum

题意:从2~N中找到  最大的 n使得  n/phi(n) 最大。

思路:直接从欧拉函数定义分析,最后的结果就是要使n质因数越多越好。JAVA大数搞定。

import java.math.BigInteger;import java.util.Scanner;public class Main {private static Scanner scan;public static void main(String[] args) {scan = new Scanner(System.in);int ncase = scan.nextInt();boolean []isPrime = new boolean[10010];for(int i = 0; i < 10010; i++){isPrime[i] = false;}BigInteger []dp = new BigInteger[10010];int []prime = new int[10010];int cnt = 1;for(int i = 2; i < 10000; i++){if(!isPrime[i]){prime[cnt++] = i;for(int j = i*i; j < 10000; j+=i){isPrime[j] = true;}}}dp[0] = BigInteger.ONE;for(int i = 1; i < cnt; i++){dp[i] = dp[i-1].multiply(BigInteger.valueOf(prime[i]));}while(ncase-->0){BigInteger n = scan.nextBigInteger();int ans = 0;int  k = 0;for(int i = 1; i < cnt; i++){if(dp[i].compareTo(n)>0){ans = i;break;}}System.out.println(dp[ans-1]);}}}


HDU4004:The Frog's Games

题意:青蛙跳过河,河宽L,有n个石头,最多条跳m次,问满足条件的最大跳跃距离中的最小值。

思路:二分答案+二分石头

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <string>#include <algorithm>#include <queue>using namespace std;const int maxn = 500000+10;int stone[maxn];int L,n,m;int dis[maxn];bool can(int x){    int s=x;    int sum=1;    while(s < L){        sum++;        if(sum > m) return false;        int tt = lower_bound(stone,stone+n+2,s)-stone;        if(stone[tt] > s){            tt--;        }        s = stone[tt]+x;    }    return true;}int main(){    while(~scanf("%d%d%d",&L,&n,&m)){        for(int i = 1; i <= n; i++) scanf("%d",&stone[i]);        stone[0] = 0;        stone[n+1] = L;        sort(stone,stone+n+2);        int l = 0,r = L;        while(l <= r){            int mid = (l+r)>>1;            if(can(mid)){                r = mid-1;            }else{                l = mid+1;            }        }        cout<<l<<endl;    }    return 0;}


HDU4006:The kth great number

题意:n次操作,操作分两种,一种是写一个数,一种查询第k大数。 (1=<k<=n<=1000000)

思路:优先队列维护前k大数。

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <string>#include <algorithm>#include <queue>using namespace std;int n,k;priority_queue<int,vector<int>,greater<int> >pq;int main(){    while(~scanf("%d%d",&n,&k)){        while(!pq.empty()) pq.pop();        char op[20];        int a;        while(n--){            scanf("%s",op);            if(op[0]=='I'){                scanf("%d",&a);                if(pq.size() == k){                    if(a > pq.top()){                        pq.pop();                        pq.push(a);                    }                }else{                    pq.push(a);                }            }else{                cout<<pq.top()<<endl;            }        }    }    return 0;}

HDU4007:Dave

题意:xoy坐标系有n个点,问你用一个边长为r的正方形去框点,最多能框多少个点

思路:水题,暴力二维扫描线

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>using namespace std;struct node{    int x,y;    node(int x,int y):x(x),y(y){}};bool cmp1(node a,node b){    if(a.x != b.x) return a.x < b.x;    else return a.y < b.y;}bool cmp2(node a,node b){    if(a.y != b.y) return a.y < b.y;    else return a.x < b.x;}vector<node> vn,nn;int n,r;int ans;int main(){    while(~scanf("%d%d",&n,&r)){        vn.clear();        ans = 0;        for(int i = 0; i < n; i++){            int a,b;            scanf("%d%d",&a,&b);            vn.push_back(node(a,b));        }        sort(vn.begin(),vn.end(),cmp1);        for(int i = 0; i < n; i++){            int j = i;            nn.clear();            while(j < vn.size() &&vn[j].x  <= vn[i].x+r){                nn.push_back(vn[j]);                j++;            }            sort(nn.begin(),nn.end(),cmp2);            for(int j = 0; j < nn.size(); j++){                int k = j;                while(k < nn.size() && nn[k].y <= nn[j].y+r) k++;                ans = max(ans,k-j);            }        }        printf("%d\n",ans);    }    return 0;}





HDU4009:Transfer water

题意:有n个房子(n<=1000),有三个参数x,y,z对应它的坐标,每个房子可以自己挖个井花费为X*x,也可以从其他房子引水管如果水源的高度低于自身高度,那么花费为曼哈顿距离*y+z,否则花费为曼哈顿距离*y。问所有用户都能有水用的最小话费。

思路:有向图的最小生成树即最小树形图,将可以引水管的房子连边,以及自己可以挖井,将自身与一个超级源点(根节点)连边,不存在无解的情况.

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>using namespace std;const int maxn = 1000+10;const int inf = 1<<25;struct house{    int a,b,c;    house(){}};vector<house> vh;struct edge{    int u,v,w;    edge(int u,int v,int w):u(u),v(v),w(w){}};vector<edge>E;int nume;int n,x,y,z;int ans;int ID[maxn],pre[maxn],to[maxn],inw[maxn];void addedge(int u,int v,int w){    E.push_back(edge(u,v,w));}inline int getDist(int x,int y){    return abs(vh[x].a-vh[y].a)+abs(vh[x].b-vh[y].b)+abs(vh[x].c-vh[y].c);}void ZhuLiu(int rt){    int t,idx,u,v;    while(true){        for(int i = 0; i < n; i++){            inw[i] = inf;            ID[i] = -1;            to[i] = -1;        }        for(int i = 0; i < nume; i++){            u = E[i].u;            v = E[i].v;            if(E[i].w < inw[v] && u != v){                inw[v] = E[i].w;                pre[v] = u;            }        }        inw[rt] = 0;        idx = 0;        for(int i = 0; i < n; i++){            t = i;            ans += inw[i];            while(to[t]!=i && ID[t]==-1 && t!=rt){                to[t] = i;                t = pre[t];            }            if(t!=rt && ID[t]==-1){                for(int u=pre[t]; u!=t; u=pre[u]){                    ID[u] = idx;                }                ID[t] = idx++;            }        }        if(idx==0) break;        for(int i = 0; i < n; i++){            if(ID[i]==-1) ID[i] = idx++;        }        for(int i = 0; i < nume; i++){            u = E[i].u;            v = E[i].v;            E[i].w -= inw[v];            E[i].u = ID[u];            E[i].v = ID[v];        }        n = idx;        rt = ID[rt];    }    printf("%d\n",ans);}void init(){    ans = 0;    vh.clear();    vh.resize(n+1);    E.clear();}int main(){    while(~scanf("%d%d%d%d",&n,&x,&y,&z) && n+x+y+z){        init();        for(int i = 1; i <= n; i++){            scanf("%d%d%d",&vh[i].a,&vh[i].b,&vh[i].c);            addedge(0,i,x*vh[i].c);        }        for(int i = 1; i <= n; i++){            int k,t;            scanf("%d",&k);            while(k--){                scanf("%d",&t);                if(t==i) continue;                if(vh[t].c > vh[i].c){                    addedge(i,t,getDist(t,i)*y+z);                }else{                    addedge(i,t,getDist(t,i)*y);                }            }        }        ++n;        nume = E.size();        ZhuLiu(0);    }    return 0;}





0 0
原创粉丝点击