• 2014ACM/ICPC亚洲区广州站 北大命题


    http://acm.hdu.edu.cn/showproblem.php?pid=5131

    现场赛第一个题,水题。题意:给水浒英雄排序,按照杀人数大到小,相同按照名字字典序小到大。输出。然后对每个查询的名字,计数有多少人杀人数大于他,输出个数加1,计数有多少人杀人数相同,但名字小,如果没有不输出,否则输出个数加1。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 using namespace std;
     5 struct G{
     6     string name;
     7     int kill;
     8     friend bool operator <(const G a,const G b){
     9         return a.kill>b.kill||(a.kill==b.kill&&a.name<b.name);
    10     }
    11 }g[512];
    12 string str;
    13 int main(){
    14     int n,m,id;
    15     while(~scanf("%d",&n),n){
    16         for(int i=0;i<n;i++){
    17             cin>>g[i].name>>g[i].kill;
    18         }
    19         sort(g,g+n);
    20         for(int i=0;i<n;i++){
    21             cout<<g[i].name<<" "<<g[i].kill<<endl;
    22         }
    23         scanf("%d",&m);
    24         while(m--){
    25             cin>>str;
    26             for(int i=0;i<n;i++){
    27                 if(str==g[i].name){
    28                     id=i;
    29                     break;
    30                 }
    31             }
    32             int ansa=1,ansb=1;
    33             for(int i=0;i<id;i++){
    34                 if(g[i].kill>g[id].kill){
    35                     ansa++;
    36                 }
    37                 else{
    38                     ansb++;
    39                 }
    40             }
    41             printf("%d",ansa);
    42             if(ansb>1){
    43                 printf(" %d",ansb);
    44             }
    45             puts("");
    46         }
    47     }
    48     return 0;
    49 }
    View Code

    http://acm.hdu.edu.cn/showproblem.php?pid=5137

    第二题,最短路。题意:给一个n点m边带权无向图,可以破坏2到n-1号中任意一个,问破坏哪个后1到n的最短路最长。做法:枚举破坏的点,对于每个最短路,求最大值。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 const int inf=0x3f3f3f3f;
     7 bool can[64];
     8 class Spfa { ///单源最短路o(2*ME)
     9     typedef int typec;///边权的类型
    10     static const int ME=2010;///边的个数
    11     static const int MV=64;///点的个数
    12     struct E {
    13         int v,next;
    14         typec w;
    15     } e[ME];
    16     int n,le,head[MV],inque[MV];
    17     typec dist[MV];
    18     bool used[MV];
    19     queue<int> q;
    20 public:
    21     void init(int tn) { ///传入点的个数
    22         n=tn;
    23         le=0;
    24         mt(head,-1);
    25     }
    26     void add(int u,int v,typec w) {
    27         e[le].v=v;
    28         e[le].w=w;
    29         e[le].next=head[u];
    30         head[u]=le++;
    31     }
    32     bool solve(int s) { ///传入起点,下标0开始,存在负环返回false
    33         for(int i=0; i<=n; i++) {
    34             dist[i]=inf;
    35             used[i]=true;
    36             inque[i]=0;
    37         }
    38         used[s]=false;
    39         dist[s]=0;
    40         inque[s]++;
    41         while(!q.empty()) q.pop();
    42         q.push(s);
    43         while(!q.empty()) {
    44             int u=q.front();
    45             q.pop();
    46             used[u]=true;
    47             for(int i=head[u]; ~i; i=e[i].next) {
    48                 int v=e[i].v;
    49                 if(can[v]) continue;
    50                 if(dist[v]>dist[u]+e[i].w) {
    51                     dist[v]=dist[u]+e[i].w;
    52                     if(used[v]) {
    53                         used[v]=false;
    54                         q.push(v);
    55                         inque[v]++;
    56                         if(inque[v]>n) return false;
    57                     }
    58                 }
    59             }
    60         }
    61         return true;
    62     }
    63     typec getdist(int id) {
    64         return dist[id];
    65     }
    66 } g;
    67 int main(){
    68     int n,m,u,v,w;
    69     while(~scanf("%d%d",&n,&m),n|m){
    70         g.init(n);
    71         while(m--){
    72             scanf("%d%d%d",&u,&v,&w);
    73             g.add(u,v,w);
    74             g.add(v,u,w);
    75         }
    76         int ans=0;
    77         for(int i=2;i<n;i++){
    78             mt(can,0);
    79             can[i]=true;
    80             g.solve(1);
    81             ans=max(ans,g.getdist(n));
    82         }
    83         if(ans==inf){
    84             puts("Inf");
    85             continue;
    86         }
    87         printf("%d
    ",ans);
    88     }
    89     return 0;
    90 }
    View Code

    http://acm.hdu.edu.cn/showproblem.php?pid=5135

    第三题,bfs。题意:给n个棒子的长度,可以任意挑3个一组组成三角形,不一定要全用完,问最后三角形之和最大是多少。做法:用二进制表示是否用过某个棒子,然后bfs。

     bfs,有vis剪了一些情况40ms,vis去掉和下面dfs一样了

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<queue>
     5 #define mt(a,b) memset(a,b,sizeof(a))
     6 using namespace std;
     7 double area_triangle(double a,double b,double c) {//计算三角形面积,输入三边长
     8     double s=(a+b+c)/2;
     9     return sqrt(s*(s-a)*(s-b)*(s-c));
    10 }
    11 double len[16],ans;
    12 bool vis[1<<12][1<<12];
    13 int n;
    14 struct Q{
    15     int sta;
    16     double area;
    17 }now,pre;
    18 queue<Q> q;
    19 bool judge(double x,double y,double z){
    20     return x+y>z&&x+z>y&&y+z>x;
    21 }
    22 void bfs(){
    23     mt(vis,0);
    24     now.sta=0;
    25     now.area=0;
    26     while(!q.empty()) q.pop();
    27     q.push(now);
    28     while(!q.empty()){
    29         pre=q.front();
    30         q.pop();
    31         ans=max(ans,pre.area);
    32         for(int i=0;i<n;i++){
    33             if((pre.sta>>i)&1) continue;
    34             for(int j=i+1;j<n;j++){
    35                 if((pre.sta>>j)&1) continue;
    36                 for(int k=j+1;k<n;k++){
    37                     if((pre.sta>>k)&1) continue;
    38                     if(!judge(len[i],len[j],len[k])) continue;
    39                     now.sta=pre.sta|(1<<i)|(1<<j)|(1<<k);
    40                     if(vis[pre.sta][now.sta]) continue;
    41                     vis[pre.sta][now.sta]=true;
    42                     now.area=pre.area+area_triangle(len[i],len[j],len[k]);
    43                     q.push(now);
    44                 }
    45             }
    46         }
    47     }
    48 }
    49 int main(){
    50     while(~scanf("%d",&n),n){
    51         for(int i=0;i<n;i++){
    52             scanf("%lf",&len[i]);
    53         }
    54         ans=0;
    55         bfs();
    56         printf("%.2f
    ",ans);
    57     }
    58     return 0;
    59 }
    View Code

     dfs暴力所有情况171ms

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 #define mt(a,b) memset(a,b,sizeof(a))
     6 using namespace std;
     7 const int M=16;
     8 int a[M],n;
     9 bool use[M];
    10 double ans;
    11 bool judge(int x,int y,int z){
    12     return x+y>z;
    13 }
    14 double area_triangle(double a,double b,double c) {//计算三角形面积,输入三边长
    15     double s=(a+b+c)/2;
    16     return sqrt(s*(s-a)*(s-b)*(s-c));
    17 }
    18 void dfs(double sum){
    19     ans=max(ans,sum);
    20     for(int i=0;i<n;i++){
    21         if(use[i]) continue;
    22         for(int j=i+1;j<n;j++){
    23             if(use[j]) continue;
    24             for(int k=j+1;k<n;k++){
    25                 if(use[k]) continue;
    26                 if(!judge(a[i],a[j],a[k])) continue;
    27                 use[i]=use[j]=use[k]=true;
    28                 dfs(sum+area_triangle(a[i],a[j],a[k]));
    29                 use[i]=use[j]=use[k]=false;
    30             }
    31         }
    32     }
    33 }
    34 int main(){
    35     while(~scanf("%d",&n),n){
    36         for(int i=0;i<n;i++){
    37             scanf("%d",&a[i]);
    38         }
    39         sort(a,a+n);
    40         mt(use,0);
    41         ans=0;
    42         dfs(0);
    43         printf("%.2f
    ",ans);
    44     }
    45     return 0;
    46 }
    View Code

     状态压缩dp,非常厉害15ms

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<vector>
     6 #define mt(a,b) memset(a,b,sizeof(a))
     7 using namespace std;
     8 const int M=16;
     9 int a[M],n;
    10 double dp[1<<12];
    11 vector<int> v;
    12 bool judge(int x,int y,int z){
    13     return x+y>z;
    14 }
    15 double area_triangle(double a,double b,double c) {//计算三角形面积,输入三边长
    16     double s=(a+b+c)/2;
    17     return sqrt(s*(s-a)*(s-b)*(s-c));
    18 }
    19 int main(){
    20     while(~scanf("%d",&n),n){
    21         for(int i=0;i<n;i++){
    22             scanf("%d",&a[i]);
    23         }
    24         sort(a,a+n);
    25         mt(dp,0);
    26         int big=1<<n;
    27         for(int i=0;i<n;i++){
    28             for(int j=i+1;j<n;j++){
    29                 for(int k=j+1;k<n;k++){
    30                     if(!judge(a[i],a[j],a[k])) continue;
    31                     int sta=(1<<i)|(1<<j)|(1<<k);
    32                     dp[sta]=area_triangle(a[i],a[j],a[k]);
    33                     v.push_back(sta);
    34                 }
    35             }
    36         }
    37         int lv=v.size();
    38         for(int i=0;i<big;i++){
    39             for(int j=0;j<lv;j++){
    40                 if(i&v[j]) continue;
    41                 int next=i|v[j];
    42                 dp[next]=max(dp[next],dp[i]+dp[v[j]]);
    43             }
    44         }
    45         printf("%.2f
    ",dp[big-1]);
    46     }
    47     return 0;
    48 }
    View Code

     http://acm.hdu.edu.cn/showproblem.php?pid=5128

    第四题,枚举。题意:给n个点,任意挑8个点构成两个不相交矩形,问能得到最大面积。做法:先处理出所有矩形,然后n^2枚举出两个矩形,如果一个矩形完全在另一个内,边不相交,那面积就是大的矩形的面积,如果相交了那是不合法的,否则就是两个矩形面积和,最后求个面积最大值。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<vector>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 struct point{
     7     int x,y;
     8 }p[32];
     9 struct G{
    10     int sx,sy,bx,by;
    11 }now;
    12 vector<G> g;
    13 bool inside(G a,G b){
    14     return a.sx>b.sx&&a.sy>b.sy&&a.bx<b.bx&&a.by<b.by;
    15 }
    16 int area(G a){
    17     return (a.bx-a.sx)*(a.by-a.sy);
    18 }
    19 bool in(int x,int y,G b){
    20     return x>=b.sx&&y>=b.sy&&x<=b.bx&&y<=b.by;
    21 }
    22 bool judge(G a,G b){
    23     return in(a.sx,a.sy,b)||in(a.sx,a.by,b)||in(a.bx,a.sy,b)||in(a.bx,a.by,b);
    24 }
    25 bool vis[210][210];
    26 int main(){
    27     int n;
    28     while(~scanf("%d",&n),n){
    29         mt(vis,0);
    30         for(int i=0;i<n;i++){
    31             scanf("%d%d",&p[i].x,&p[i].y);
    32             vis[p[i].x][p[i].y]=true;
    33         }
    34         g.clear();
    35         for(int i=0;i<n;i++){
    36             for(int j=0;j<n;j++){
    37                 if(p[i].x<p[j].x&&p[i].y<p[j].y){
    38                     if(!vis[p[i].x][p[j].y]) continue;
    39                     if(!vis[p[j].x][p[i].y]) continue;
    40                     now.sx=p[i].x;
    41                     now.sy=p[i].y;
    42                     now.bx=p[j].x;
    43                     now.by=p[j].y;
    44                     g.push_back(now);
    45                 }
    46             }
    47         }
    48         int lg=g.size();
    49         int ans=0;
    50         for(int i=0;i<lg;i++){
    51             for(int j=i+1;j<lg;j++){
    52                 if(inside(g[i],g[j])||inside(g[j],g[i])){
    53                     ans=max(ans,max(area(g[i]),area(g[j])));
    54                     continue;
    55                 }
    56                 if(judge(g[i],g[j])||judge(g[j],g[i])) continue;
    57                 ans=max(ans,area(g[i])+area(g[j]));
    58             }
    59         }
    60         if(!ans){
    61             puts("imp");
    62             continue;
    63         }
    64         printf("%d
    ",ans);
    65     }
    66     return 0;
    67 }
    View Code

    A

    题目:1 x y加入x,y  ; -1 x y删去 x,y  ; 0 a b 查询之前加入的x*a+y*b最大值

    暴力n2能过,标程比暴力还慢。。

     1 #include<cstdio>
     2 typedef long long LL;
     3 const int M=5e4+10;
     4 struct G{
     5     LL x,y;
     6     bool flag;
     7 }q[M];
     8 int main(){
     9     int n,a;
    10     LL b,c;
    11     while(~scanf("%d",&n),n){
    12         int lq=0;
    13         while(n--){
    14             scanf("%d%lld%lld",&a,&b,&c);
    15             if(a==1){
    16                 q[lq].x=b;
    17                 q[lq].y=c;
    18                 q[lq].flag=true;
    19                 lq++;
    20                 continue;
    21             }
    22             if(a==-1){
    23                 for(int i=0;i<lq;i++){
    24                     if(!q[i].flag) continue;
    25                     if(q[i].x==b&&q[i].y==c){
    26                         q[i].flag=false;
    27                         break;
    28                     }
    29                 }
    30                 continue;
    31             }
    32             LL ans=-4e18,tmp;
    33             for(int i=0;i<lq;i++){
    34                 if(!q[i].flag) continue;
    35                 tmp=q[i].x*b+q[i].y*c;
    36                 if(ans<tmp){
    37                     ans=tmp;
    38                 }
    39             }
    40             printf("%lld
    ",ans);
    41         }
    42     }
    43     return 0;
    44 }
    View Code

    end

  • 相关阅读:
    hashlib模块
    sys模块
    random模块
    time模块
    生成器、迭代器
    装饰器
    函数相关内容
    集合相关操作
    springcloud(四):Eureka的配置详解
    springcloud(二):Eureka服务注册与发现
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/4207083.html
Copyright © 2020-2023  润新知