• 哈尔滨理工大学第七届程序设计竞赛初赛(高年级组)


    https://www.nowcoder.com/acm/contest/27#question

       A-凌波微步

      LIS恐成最大输家,无力吐槽 = =

    B-C水题

    D-经商

    小d是一个搞房地产的土豪。每个人经商都有每个人经商的手段,当然人际关系是需要放在首位的。

    小d每一个月都需要列出来一个人际关系表,表示他们搞房地产的人的一个人际关系网,但是他的精力有限,对应他只能和能够接触到的人交际。比如1认识2,2认识3,那么1就可以接触3进行交际,当然1和2也可以交际。

    小d还很精明,他知道他和谁交际的深获得的利益大,接下来他根据自己的想法又列出来一个利益表,表示他和这些人交际需要耗用多少精力,能够获得的利益值为多少。

    小d想知道,他在精力范围内,能够获得的利益值到底是多少。

    设定小d自己的编号为1.并且对应一个人的交际次数限定为1.

    输入描述:

    本题包含多组输入,第一行输入一个数t,表示测试数据的组数
    每组数据的第一行输入三个数,N,M,C,表示这个人际关系网一共有多少个人,关系网的关系数,以及小d的精力值
    接下来N-1行,每行两个数ai,bi。这里第i行表示和编号为i+1的人认识需要花费ai的精力,能够获得的利益值为bi。
    再接下来M行,每行两个数x,y,表示编号为x的人能够和编号为y的人接触
    t<=50
    2<=N<=10000
    1<=M<=10*N
    1<=ai,bi<=10
    1<=C<=500
    1<=x,y<=N

    输出描述:

    输出包含一行,表示小d能够获得的最大利益值
    示例1

    输入

    1
    5 3 7
    5 10
    3 2
    4 3
    1 100
    1 2
    2 3
    1 4

    输出

    10
    并查集统计出1所有能接触到的人+背包求解最优值
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int f[10005],dp[550];
     4 int getf(int v){return f[v]==v?v:f[v]=getf(f[v]);}
     5 struct node
     6 {
     7     int a,b;
     8 }P[10005],Q[10005];
     9 int main()
    10 {
    11     int T,N,M,C,i,j,k,x,y;
    12     scanf("%d",&T);
    13     while(T--){int sq=0;
    14     memset(dp,0,sizeof(dp));
    15         scanf("%d%d%d",&N,&M,&C);
    16         for(i=1;i<=N;++i) f[i]=i;
    17         for(i=2;i<=N;++i)
    18         {
    19             scanf("%d%d",&P[i].a,&P[i].b);
    20         }
    21         for(i=1;i<=M;++i)
    22         {
    23             scanf("%d%d",&x,&y);
    24             int fx=getf(x),fy=getf(y);
    25             if(fx!=fy){
    26                 f[fx]=fy;
    27             }
    28         }
    29         for( i=1;i<=N;++i) f[i]=getf(i);
    30         int root=f[1];
    31         for(i=2;i<=N;++i)
    32         {
    33             if(f[i]==root){
    34                 Q[++sq]=P[i];
    35             }
    36         }
    37         for(i=1;i<=sq;++i)
    38         {
    39             for(j=C;j>=Q[i].a;--j)
    40                 dp[j]=max(dp[j],dp[j-Q[i].a]+Q[i].b);
    41         }
    42         cout<<dp[C]<<endl;
    43     }
    44     return 0;
    45 }
    F-苦逼的单身狗
    尺取法,枚举左边界,指定情况出现时再指定情况未消失时不断右移左边界并统计数量。
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 char s[100005];
     4 int vis[5];
     5 int zh[30];
     6 #define inf 0x3f3f3f3f
     7 int main()
     8 {
     9     int t,n,m,i,j,k;
    10     zh['L']=1;
    11     zh['O']=2;
    12     zh['V']=3;
    13     zh['E']=4;
    14     cin>>t;
    15     while(t--){
    16             cin>>s;
    17             memset(vis,0,sizeof(vis));
    18     int len=strlen(s);
    19     long long ans=0;
    20     int cur=0;
    21     for(i=0;i<len;++i)
    22     {
    23        k=zh[s[i]];
    24        if(k){
    25         vis[k]++;
    26        }
    27        while(cur<=i&&vis[4]&&vis[1]&&vis[2]&&vis[3]){
    28         ans+=(long long )len-i;//cout<<len-i<<endl;
    29         if(zh[s[cur]]) vis[zh[s[cur]]]--;
    30         cur++;
    31        }
    32     }
    33     printf("%lld
    ",ans);
    34     }
    35     return 0;
    36 }
    
    

    H-布置会场

    矩阵幂裸题。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<iostream>
     5 using namespace std;
     6 #define LL long long
     7 LL M=1000000007;
     8  
     9 struct Matrix {
    10     long long a[2][2];
    11     Matrix() {
    12         memset(a, 0, sizeof(a));
    13     }
    14     Matrix operator * (const Matrix y) {
    15         Matrix ans;
    16         for(int i = 0; i <= 1; i++)
    17             for(int j = 0; j <= 1; j++)
    18                 for(int k = 0; k <= 1; k++)
    19                     ans.a[i][j] += a[i][k]*y.a[k][j];
    20         for(int i = 0; i <= 1; i++)
    21             for(int j = 0; j <= 1; j++)
    22                 ans.a[i][j] %= M;
    23         return ans;
    24     }
    25     void operator = (const Matrix b) {
    26         for(int i = 0; i <= 1; i++)
    27             for(int j = 0; j <= 1; j++)
    28                 a[i][j] = b.a[i][j];
    29     }
    30 };
    31  
    32 int solve(long long x) {
    33     Matrix ans, trs;
    34     ans.a[0][0] = ans.a[1][1] = 1;
    35     trs.a[0][0] = trs.a[1][0] = trs.a[0][1] = 1;
    36     while(x) {
    37         if(x&1)
    38             ans = ans*trs;
    39         trs = trs*trs;
    40         x >>= 1;
    41     }
    42     return ans.a[0][0];
    43 }
    44  
    45 int main() {
    46     long long n;
    47     int t;
    48     cin>>t;
    49     while(t--){
    50     scanf("%lld", &n);
    51     cout << solve(n) << endl;
    52     }
    53     return 0;
    54 }
    I-旅行
    最短路+思维。
    题目很显然就是求最大化的{任意有两条最短路连接的三个点中的这两条最短路径长度和},其中三个点互不相等。
    首先我们要求出任意两点间的最短路这是肯定的,有N^3的floyd或是N*N*log(N)的dij,前者肯定炸了。对于后面的找这三个点的过程一直想的是N*N*N,这样的话无论最短路算法在再优化也会T,比赛时迫于时间
    直接暴力了个floyd直接炸了。
    其实找点用不到这么麻烦,题目求得时最大化的,三个点显然只有两条最短路,我们枚举1-n作为中转点,没次找到中转点对于其他点最大的两条最短路更新答案就好了。这样找的复杂度就降到了N^2不会T了。
    好题。
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define inf 0x3f3f3f3f
     4 struct Edge
     5 {
     6     int to,w,next;
     7 }e[2010];
     8 int first[1010],cnt;
     9 struct node
    10 {
    11     int u,w;
    12     bool operator<(const node& t)const{
    13     return w>t.w;
    14     }
    15 };
    16 void add(int u,int v,int w)
    17 {
    18     e[cnt].to=v;
    19     e[cnt].w=w;
    20     e[cnt].next=first[u];
    21     first[u]=cnt++;
    22 }
    23 int d[1005][1005];
    24 bool vis[1005];
    25 void dij(int u,int n)
    26 {
    27     priority_queue<node>Q;
    28     node t1,t2;
    29     memset(vis,0,sizeof(vis));
    30     d[u][u]=0;
    31     Q.push(node{u,0});
    32     while(!Q.empty()){
    33         t1=Q.top();
    34         Q.pop();
    35         if(vis[t1.u]) continue;
    36         vis[t1.u]=1;
    37         for(int i=first[t1.u];i+1;i=e[i].next){
    38             if(d[u][e[i].to]>d[u][t1.u]+e[i].w){
    39                 d[u][e[i].to]=d[u][t1.u]+e[i].w;
    40                 Q.push(node{e[i].to,d[u][e[i].to]});
    41             }
    42         }
    43     }
    44 }
    45 int main()
    46 {
    47     int t,n,m,i,j,k,u,v,w;
    48     cin>>t;
    49     while(t--){
    50         cin>>n>>m;
    51         memset(first,-1,sizeof(first));
    52         memset(d,inf,sizeof(d));
    53         cnt=0;
    54         for(i=1;i<=m;++i)
    55         {
    56             scanf("%d%d%d",&u,&v,&w);
    57             add(u,v,w);
    58             add(v,u,w);
    59         }
    60         for(i=1;i<=n;++i) dij(i,n);
    61         int ans=-1;
    62         for(i=1;i<=n;++i)
    63         {
    64             int t1=-1,t2=-1,maxn=0;
    65             for(j=1;j<=n;++j)
    66             {
    67                 if(d[i][j]!=inf&&d[i][j]>maxn){
    68                     maxn=d[i][j];
    69                     t1=j;
    70                 }
    71             }
    72             maxn=0;
    73             for(j=1;j<=n;++j)
    74             {
    75                 if(j!=t1&&d[i][j]!=inf&&d[i][j]>maxn){
    76                     maxn=d[i][j];
    77                     t2=j;
    78                 }
    79             }
    80             if(t1!=-1&&t2!=-1){
    81                 ans=max(ans,d[i][t1]+d[i][t2]);
    82             }
    83         }
    84         printf("%d
    ",ans);
    85     }
    86     return 0;
    87 }
    
    
    


  • 相关阅读:
    创建对象_原型(Prototype)模式_深拷贝
    创建对象_工厂方法(Factory Method)模式 与 静态工厂方法
    创建对象——单例(Singleton)模式
    模板方法模式
    移除HTML5 input在type="number"时的上下小箭头
    颜色名列表
    什么是盒模型?
    JQuery中$.ajax()方法参数详解
    zsh下docker命令tab补全方法
    ubuntu14.04 搭建gitlab服务
  • 原文地址:https://www.cnblogs.com/zzqc/p/8016242.html
Copyright © 2020-2023  润新知