zoukankan      html  css  js  c++  java
  • 牛客练习赛17

     A.
    链接:https://www.nowcoder.com/acm/contest/109/A
    来源:牛客网

    题目描述

    给出共享长方体一个顶点的三个面的面积,求它十二条边的边长和。

    输入描述:

    一行三个整数a, b, c表示面积(1 <= a, b, c <= 10000)。

    输出描述:

    一行一个整数表示边长和。
    示例1

    输入

    1 1 1

    输出

    12
    示例2

    输入

    4 6 6

    输出

    28

    设三边长度为A,B,C,则有a=AB,b=BC,c=AC,枚举一下B如果满足B是a和b的因子且能满足c=AC,就直接计算输出结果。
        
     1 #include<iostream>
     2 #include<cstring>
     3 #include<queue>
     4 #include<cstdio>
     5 #include<stack>
     6 #include<set>
     7 #include<map>
     8 #include<cmath>
     9 #include<ctime>
    10 #include<time.h> 
    11 #include<algorithm>
    12 using namespace std;
    13 #define mp make_pair
    14 #define pb push_back
    15 #define debug puts("debug")
    16 #define LL long long 
    17 #define pii pair<int,int>
    18 #define eps 1e-10
    19 int gcd(int a,int b){
    20     return b==0?a:gcd(b,a%b);
    21 }
    22 int main()
    23 {
    24     int n,m,i,j,k;
    25     LL a,b,c;
    26     LL A,B,C;
    27     cin>>a>>b>>c;
    28     n=max(a,b);
    29     for(B=1;B<=n;++B){
    30         if(a%B==0&&b%B==0){
    31             if(c==a/B*b/B){
    32                 cout<<4*(B+a/B+b/B)<<endl;
    33                 return 0;
    34             }
    35         }
    36     }
    37     return 0; 
    38 }


    B.
    链接:https://www.nowcoder.com/acm/contest/109/B
    来源:牛客网

    题目描述

    给出两个串s和x
    定义s中的某一位i为好的位置,当且仅当存在s的子序列 满足y=x且存在j使得i=kj成立。
    问s中是否所有的位置都是好的位置。

    输入描述:

    一行两个字符串s,x,这两个串均由小写字母构成。
    1 <= |s|, |x| <= 200000

    输出描述:

    Yes表示是。
    No表示不是。
    示例1

    输入

    abab
    ab

    输出

    Yes
    示例2

    输入

    abacaba
    aba

    输出

    No
    示例3

    输入

    abc
    ba

    输出

    No

    kmp跑一波遇见怎么也无法匹配的点就输出no即可。
        
     1 #include<iostream>
     2 #include<cstring>
     3 #include<queue>
     4 #include<cstdio>
     5 #include<stack>
     6 #include<set>
     7 #include<map>
     8 #include<cmath>
     9 #include<ctime>
    10 #include<time.h> 
    11 #include<algorithm>
    12 using namespace std;
    13 #define mp make_pair
    14 #define pb push_back
    15 #define debug puts("debug")
    16 #define LL long long 
    17 #define pii pair<int,int>
    18 #define eps 1e-10
    19 LL R=6371009;
    20 int f[202020];
    21 int g[202020];
    22 char s[202020];
    23 char x[202020];
    24 int main()
    25 {
    26     int n,m,i,j,k;
    27     double x1,y1,x2,y2;
    28     scanf("%s%s",s,x);
    29     int n1=strlen(s);
    30     int n2=strlen(x);
    31     f[0]=-1;
    32     for(i=1;i<=n2;++i){
    33         j=f[i-1];
    34         while(j!=-1&&x[i-1]!=x[j]) j=f[j];
    35         f[i]=j+1;
    36     }
    37     for(i=0,j=0;i<n1;++i){
    38         if(s[i]==x[j]){
    39             j++;
    40         }
    41         else{
    42             while(j!=-1&&x[j]!=s[i]) j=f[j];
    43             j++;
    44         }
    45         if(j==n2){
    46             g[i]=n2;
    47             j=f[j];
    48         //    j++;
    49         }
    50     }
    51     int l=n1;
    52     bool ok=1;
    53 //    for(i=0;i<n1;++i)
    54 //    cout<<"gi="<<g[i]<<endl;
    55     for(i=n1-1;i>=0;--i){
    56         if(g[i]==0&&l>=i){
    57             ok=0;
    58             break;
    59         }
    60         if(g[i]){
    61             l=i-n2;
    62         }
    63     }
    64     ok?puts("Yes"):puts("No");
    65     return 0; 
    66 }
    67 
    68 /*
    69 ababbab
    70 ab
    71 */


    C.
    链接:https://www.nowcoder.com/acm/contest/109/C
    来源:牛客网

    题目描述

    给定长度为n的数组a,定义一次操作为:
    1. 算出长度为n的数组s,使得si= (a[1] + a[2] + ... + a[i]) mod 1,000,000,007;
    2. 执行a = s;
    现在问k次操作以后a长什么样。

    输入描述:

    第一行两个整数n,k(1 <= n <= 2000, 0 <= k <= 1,000,000,000);
    第二行n个整数表示a数组(0 <= a
    i
    <= 1,000,000,000)。

    输出描述:

    一行n个整数表示答案。
    示例1

    输入

    3 1
    1 2 3

    输出

    1 3 6
    示例2

    输入

    5 0
    3 14 15 92 6

    输出

    3 14 15 92 6

        首先注意到这个操作可以用矩阵来表示,设原数组为一个行向量A,k次操作之后得到的行向量B, 转移矩阵为X,则有A*Xk=B ,观察发现X是一个N*N的上三角矩阵,

      可即使使用了快速幂,这个矩阵一次乘法的时间复杂度也不允许接受,因为N<=2000,N^3过于庞大,枚举了这个矩阵的前几次方之后发现一个规律,这个矩阵只要知道
    第一行的元素就可以推出这个全部的矩阵,每一列都来自于第一行的一个子段,再观察发现这些数字都是杨辉三角里的数,准确的说这一行数对应杨辉三角的一列(斜着),
    对于X^k,这个矩阵,第一行的元素就是( C(k-1,0) , C(k,1) , C(k+1,2),.....C(k+n-2,n-1)),组合数的公式C(n,r)=C(n,r-1)*(n-r+1)/r,
    C(n,r)=C(n-1,r)+C(n-1,r-1),联立得出C(n,r)=C(n-1,r-1)*n/r,有除法记得取逆元。
      
     1 #include<iostream>
     2 #include<cstring>
     3 #include<queue>
     4 #include<cstdio>
     5 #include<stack>
     6 #include<set>
     7 #include<map>
     8 #include<cmath>
     9 #include<ctime>
    10 #include<time.h> 
    11 #include<algorithm>
    12 using namespace std;
    13 #define mp make_pair
    14 #define pb push_back
    15 #define debug puts("debug")
    16 #define LL long long 
    17 #define pii pair<int,int>
    18 #define eps 1e-10
    19 double R=6371009;
    20 
    21 LL MOD=1e9+7;
    22 LL q[2020];
    23 LL a[2020];
    24  void gcd(LL a,LL b,LL &d,LL &x,LL &y)
    25   {
    26       if(!b) {d=a;x=1;y=0;}
    27       else {gcd(b,a%b,d,y,x);y-=x*(a/b);}
    28   }
    29  LL inv(LL a,LL n)
    30  {
    31    LL d,x,y;
    32    gcd(a,n,d,x,y);
    33    return d==1?(x+n)%n:-1;
    34  }
    35 int main()
    36 {
    37     LL n,m,i,j,k;
    38     scanf("%lld%lld",&n,&k);
    39     for(i=1;i<=n;++i) scanf("%lld",a+i);
    40     k--;
    41     q[1]=1;
    42     for(i=2;i<=n;++i){
    43         q[i]=q[i-1]*((k+i-1)%MOD)%MOD*inv(i-1,MOD);
    44         q[i]%=MOD;
    45     }
    46     //for(i=2;i<=n;++i) q[i]+=q[i-1],q[i]%=MOD;
    47     for(i=1;i<=n;++i){
    48         LL tmp=0;
    49         for(j=1;j<=i;++j){
    50             tmp+=a[j]*q[i-j+1];
    51             tmp%=MOD;
    52         }
    53         printf("%lld%c",tmp,i==n?'
    ':' ');
    54     }
    55     return 0; 
    56 }
    
    
    
     E.
    链接:https://www.nowcoder.com/acm/contest/109/E
    来源:牛客网

    题目描述

    
    
    给定一幅n个点m条边的图和S个一定要经过的点,问从0号点出发,经过这S个点再回到0号点的最短路径长度是多少。

    输入描述:

    第一行一个整数T(T <= 2)表示数据组数。
    对于每组数据,第一行两个整数n,m表示点数和边数(1 <= n, m <= 100,000)。
    接下来m行,每行三个整数x, y, z(0 < x, y < n, 0 <= z <= 1000)表示xy之间有一条长度为c的双向边;
    接下来一个整数S。(S<=10)
    接下来S行每行一个整数表示一定要经过的点。
    数据保证有解。

    输出描述:

    T行,每行一个整数表示答案。
    示例1

    输入

    1
    4 6
    0 1 1
    1 2 1
    2 3 1
    3 0 1
    0 2 5
    1 3 5
    3
    1
    2
    3

    输出

    4

        全卡在C没来得及看这个其实不难,跑S+1(0和必经的S个点)次最短路,将点离散化然后dp,f[S][i]表示当前走的点的集合S且最后一个经过的点为i点的最短路径,
    最后枚举全集加上dis(0,i)即可。优先队列忘记重载比较算子神特么过了样例结果一直WA,还有前向星蜜汁写错,可能老了= =
        
      1 #include<iostream>
      2 #include<cstring>
      3 #include<queue>
      4 #include<cstdio>
      5 #include<stack>
      6 #include<set>
      7 #include<map>
      8 #include<cmath>
      9 #include<ctime>
     10 #include<time.h> 
     11 #include<algorithm>
     12 using namespace std;
     13 #define mp make_pair
     14 #define pb push_back
     15 #define debug puts("debug")
     16 #define LL long long 
     17 #define pii pair<int,int>
     18 #define eps 1e-10
     19 #define inf 0x3f3f3f3f
     20 struct Edge{
     21     int v,w,next;
     22 }e[202020];
     23 int first[101010],tot;
     24 void add(int u,int v,int w){
     25     e[tot].v=v;
     26     e[tot].w=w;
     27     e[tot].next=first[u];
     28     first[u]=tot++;
     29 }
     30 int f[(1<<12)][12];
     31 int d[12][101010];
     32 bool vis[101010];
     33 int x[15];
     34 int N,M,S;
     35 void dij(int s,int ps){
     36     memset(vis,0,sizeof(vis));
     37     d[ps][s]=0;
     38     priority_queue<pii,vector<pii>,greater<pii> >q;
     39     q.push(mp(0,s));
     40     while(!q.empty()){
     41         int u=q.top().second;
     42         q.pop(); 
     43         if(vis[u]) continue;
     44         vis[u]=1;
     45         for(int i=first[u];i!=-1;i=e[i].next){
     46             int v=e[i].v,w=e[i].w;
     47             if(d[ps][v]>d[ps][u]+w){
     48                 d[ps][v]=d[ps][u]+w;
     49                 q.push(mp(d[ps][v],v));
     50             }
     51         }
     52     }
     53 }
     54 
     55 int main()
     56 {
     57     int t,i,j,k;
     58     scanf("%d",&t);
     59     while(t--){
     60         memset(d,inf,sizeof(d));
     61         memset(first,-1,sizeof(first));
     62         tot=0;
     63         int u,v,w;
     64         scanf("%d%d",&N,&M);
     65         while(M--){
     66             scanf("%d%d%d",&u,&v,&w);
     67             add(u,v,w);
     68             add(v,u,w);
     69         }
     70         
     71 
     72         scanf("%d",&S);
     73         dij(0,0);
     74         x[0]=0;
     75         for(i=1;i<=S;++i){
     76             scanf("%d",&u);
     77             x[i]=u;
     78             dij(u,i);
     79         }
     80         memset(f,inf,sizeof(f));
     81         f[1][0]=0;
     82         for(int s=0;s<=(1<<(S+1));s++){
     83             for(j=0;j<=S;++j){
     84                 if(f[s][j]!=inf){
     85                     for(int k=0;k<=S;++k){
     86                         if((s&(1<<k))==0&&d[j][x[k]]!=inf){
     87                             f[s|(1<<k)][k]=min(f[s|(1<<k)][k],f[s][j]+d[j][x[k]]);
     88                         }
     89                     }
     90                 }
     91             }
     92         }
     93         
     94         int ans=inf;
     95         int all=(1<<(S+1))-1;
     96         for(i=0;i<=S;++i)
     97             ans=min(ans,f[all][i]+d[0][x[i]]);
     98         cout<<ans<<endl;
     99     }
    100     return 0; 
    101 }
    
    
     
  • 相关阅读:
    flex
    IOCP三:多个接收
    IOCP三:多个接收
    IOCP二:同时发送和接收
    IOCP二:同时发送和接收
    IOCP一:AcceptEx
    IOCP一:AcceptEx
    字符串和数字相互转换
    字符串和数字相互转换
    QThread应用详解
  • 原文地址:https://www.cnblogs.com/zzqc/p/8995135.html
Copyright © 2011-2022 走看看