zoukankan      html  css  js  c++  java
  • 2019HDU多校第十场

    (撒花!二十场打完了。虽然题解(riji)咕咕咕了好几场。

    1003 Valentine's Day

    传送:http://acm.hdu.edu.cn/showproblem.php?pid=6693

    题意:每个物品有一个能够快乐的概率$p_i$,问在$n$个物品中选择若干个,能够只快乐一次的最大概率为多少。

    数据范围:$1<=n<=10000$。

    分析:排序,依此选择最大,次大,……然后什么一个式子就过了?

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e4+100;
     4 double p[maxn];
     5 bool cmp(double A,double B) {return A>B;}
     6 void rua()
     7 {
     8     int n;scanf("%d",&n);
     9     double ans=0.0,res=0.0,tmp=1.0;
    10     for (int i=1;i<=n;i++) scanf("%lf",&p[i]);
    11     sort(p+1,p+1+n,cmp);
    12     if(p[1]==1.0) {printf("%.12lf
    ",p[1]);return;}
    13     for (int i=1;i<=n;i++) 
    14     {
    15         double kk=1.0-p[i];
    16         tmp*=kk;
    17         double tt=p[i]/kk;
    18         res+=tt;
    19         ans=max(ans,tmp*res);
    20     }
    21     printf("%.12lf
    ",ans);
    22     return;
    23 }
    24 int main()
    25 {
    26     int t;scanf("%d",&t);
    27     while(t--) rua();
    28     return 0;
    29 }
    1003

    1005 Welcome Party

    传送:http://acm.hdu.edu.cn/showproblem.php?pid=6695

    题意:有$n$个人,每个人有两个值$a_i,b_i$,每个人只能属于集合A(只参考$a_i$)或集合B(只参考$b_i$),定义每个集合的价值为集合中的最大值。要求求两个集合价值的最小差值。

    数据范围:$2<=n<=100000,0<=a_i,b_i<=10^{18}$。

    分析:考虑怎么维护最小的差值。对于$a_i$从小到大排序,然后每次枚举集合A的最大值。

    假设$a_i$为集合A的最大值,那么在$i$之后的数一定在集合B内,这个最大值可以用过预处理得到。假设这个最大值为$bb$。

    那么对于$i$之前的数我们就考虑能不能归到集合B,使得再找到一个更优的答案即可。

    如果之前的$b_i<=bb$,对于答案没有贡献。那么我们需要找的是一个数距离$a_i$更近,且大于$bb$。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=1e5+10;
     5 const ll INF=1e18+10;
     6 struct node{ll x,y;}a[maxn];
     7 bool cmp(node p,node q){return p.x<q.x;}
     8 set<ll>s;   ll mx[maxn];
     9 int main(){
    10     int t,n;scanf("%d",&t);
    11     while (t--){
    12         scanf("%d",&n);
    13         for (int i=1;i<=n;i++)scanf("%lld%lld",&a[i].x,&a[i].y);
    14         sort(a+1,a+1+n,cmp);
    15         ll mxx=0; mx[n+1]=0;
    16         for (int i=n;i>=1;i--){
    17             if (a[i].y>mxx) mxx=a[i].y;
    18             mx[i]=mxx;
    19         }
    20         s.clear();ll ans=INF;
    21         for (int i=1;i<=n;i++){
    22             ll aa=a[i].x,bb=mx[i+1];
    23             if(i!=n) ans=min(ans,abs(bb-aa));
    24             if(!ans) break;
    25             if (bb>aa||s.empty()) {s.insert(a[i].y);continue;}
    26             auto it=s.lower_bound(aa);
    27             if(it!=s.end()) ans=min(ans,abs((*it)-aa));
    28             if(it!=s.begin()){
    29                 --it;
    30                 ans=min(ans,abs((*it)-aa));
    31             }
    32             if(!ans) break;
    33             s.insert(a[i].y);
    34         }
    35         printf("%lld
    ",ans);
    36     }
    37     return 0;
    38 }
    1005

    1009 Block Breaker

    传送:http://acm.hdu.edu.cn/showproblem.php?pid=6699

    题意:有一个大小为$n*m$的方格矩阵,击打$q$次,问每次击打掉落的块数为多少。每个块掉落的定义为左右至少有一个块不存在,上下至少有一个块不存在。

    数据范围:$1<=n,m<=2000,1<=q<=100000$。

    分析:开始觉得迷惑为什么大家都会。然后仔细想了想,最多就$n*m$个块会被击落,如果这个块已经不在了,答案就是0,也不会影响到别的块。那么每次就考虑击打一个块能够影响到周围的情况。宽搜就好啦!

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=2007;
     4 int vis[maxn][maxn];
     5 int n,m,q;
     6 int dx[]={0,0,1,-1};
     7 int dy[]={1,-1,0,0};
     8 struct node{int x,y;};
     9 bool check(int x,int y)
    10 {
    11     int numx=0,numy=0;
    12     for (int i=0;i<4;i++)
    13     {
    14         int xx=x+dx[i],yy=y+dy[i];
    15         if (xx<1 || xx>n || yy<1 || yy>m) continue;
    16         if (vis[xx][yy]){
    17             if (i==0 || i==1) numx++; 
    18             else numy++;
    19         }
    20     }
    21     return (numx>=1 && numy>=1);
    22 } 
    23 
    24 int bfs(int x,int y)
    25 {
    26     queue<node> Q;
    27     node cur,nex;
    28     cur.x=x;cur.y=y;
    29     Q.push(cur);vis[x][y]=1;
    30     int res=0;
    31     while (!Q.empty())
    32     {
    33         cur=Q.front();Q.pop(); res++; 
    34         for (int i=0;i<4;i++)
    35         {
    36             int xx=cur.x+dx[i],yy=cur.y+dy[i];
    37             if (xx<1 || xx>n || yy<1 || yy>m) continue;
    38             if(check(xx,yy) && !vis[xx][yy])
    39             {
    40                 nex.x=xx;nex.y=yy;
    41                 Q.push(nex);
    42                 vis[xx][yy]=1;
    43             }
    44         }
    45     }
    46     return res;
    47 }
    48 void rua()
    49 {
    50     scanf("%d%d%d",&n,&m,&q);
    51     for (int i=0;i<=n;i++) for (int j=0;j<=m;j++) vis[i][j]=0;
    52     while (q--)
    53     {
    54         int x,y;scanf("%d%d",&x,&y);
    55         int ans;
    56         if(vis[x][y]) ans=0;
    57         else ans=bfs(x,y);
    58         printf("%d
    ",ans);
    59     }
    60     return;
    61 }
    62 int main()
    63 {
    64     int t;scanf("%d",&t);
    65     while(t--) rua();
    66     return 0;
    67 }
    1009

    1011 Make Rounddog Happy

    题解传送:https://www.cnblogs.com/changer-qyz/p/11392174.html

     

     

  • 相关阅读:
    大数据时代:基于微软案例数据库数据挖掘知识点总结(Microsoft 时序算法)
    大数据时代:基于微软案例数据库数据挖掘知识点总结(结果预测篇)
    svg图片的缩放拖拽
    计算机网络之以太网,通俗点的说法
    yield 与生成器
    安卓开发第一记 android stdio 安装后 新建测试项目报错
    Javascript的异常捕获机制
    小而实用的工具插件集锦(JQGrid,zTree)
    proxifier 注册码 +电脑全局代理设置
    雷林鹏分享:jsp 发送邮件
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/11392173.html
Copyright © 2011-2022 走看看