• 2019吉林省赛


    A.

    题意:已知$a,b,c,k$,每次操作为:

    1.If a>b then a = a - b.
    2.If b>c then b = b - c.
    3.If c>a then c = c - a.

    操作k次后,询问最终的$a,b,c$为多少?

    分析:暴力模拟即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int main(){
     4     int t;scanf("%d",&t);
     5     int x,y,z,k;
     6     while (t--){
     7         scanf("%d%d%d%d",&x,&y,&z,&k);
     8         while (k>0){
     9             if(x==y && y==z) break;
    10             if (x>y) x-=y;
    11             if (y>z) y-=z;
    12             if (z>x) z-=x;
    13             k--;
    14         }
    15         printf("%d %d %d
    ",x,y,z);
    16     }
    17     return 0;
    18 }
    A

    B.

    题意:已知一棵n个结点的树,首先有以下两个定义:

      礼物边:不存在相邻边与他颜色相同。

      礼物点:在某一棵树内,从x点开始的路径均为礼物边。

    每次询问x,即以x为根的子树内礼物节点的个数为多少。

    分析:

      比赛的时候题意一直读不通(事实上是,赛场后题意也读不懂。至今和队友还是有题意纠结???但是两份代码都过了??数据是真的水。

    考虑每次询问x时,有这样两种情况是不满足定义的:

      1. 父亲到x与x到儿子的颜色相同。这种情况下,对于以父亲为根的子树内,父亲本身是不满足题意要求的。

      2. 点x存在去往两个儿子的边颜色相同。这种情况下,我们不再需要考虑对于这两个儿子子树对于答案的贡献,可以直接无视这两个儿子子树了。

    代码:(来自xjb大佬,我写了一份假代码。我hacak我自己.jpg

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define N 200005
     4 #define P pair<int,int>
     5 using namespace std;
     6 int n,l,r,c,x,f[N];
     7 vector<P>G[N];
     8 int dfs(int x,int fa,int lstc){
     9     f[x]=1;
    10     int num=0,num1=0;
    11     map<int,int>mp;
    12     for(auto u:G[x])
    13     if(u.first!=fa){        
    14         int tmp=dfs(u.first,x,u.second);
    15         if(mp.find(u.second)!=mp.end()) mp[u.second]=0;else mp[u.second]=tmp;
    16         if(u.second==lstc) f[fa]=0;
    17     }
    18     for(auto u:mp){
    19         num+=u.second;
    20         if(u.first!=lstc) num1+=u.second;
    21     }
    22     num1+=f[x];
    23     f[x]+=num;
    24     return num1;
    25 }
    26 int main(){
    27     scanf("%d",&n);
    28     for(int i=1;i<n;i++){
    29         scanf("%d%d%d",&l,&r,&c);
    30         G[l].push_back(P(r,c));
    31         G[r].push_back(P(l,c));
    32     }
    33     dfs(1,-1,-1);
    34     int Q;
    35     scanf("%d",&Q);
    36     while(Q--){
    37         scanf("%d",&x);
    38         printf("%d
    ",f[x]);
    39     }
    40 }
    B

    另:指路队友博客题解:dfs序+差分。https://blog.csdn.net/qq_43813163/article/details/95348450

    D.

    题意:已知一棵n个节点的树,对于任一一个点集S,询问答案$sum_{ssubset S}f(s)$。其中对于$f(s)$的定义为:$f(s)=a[LCA(S)] (s 非空)$。

    分析:题意可以变为对于每一个结点x,他对于整个题答案的贡献为多少,即他出现在了多少个集合之中。考虑每一个点的时候,考虑x作为一个集合S的LCA出现的次数即可。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=1e5+10;
     5 const ll mod=1e9+7;
     6 vector<int> mp[maxn];
     7 int sz[maxn],a[maxn];
     8 ll ans;
     9 ll pow_(int x,int y){
    10     ll res=1ll,base=1ll*x;
    11     while (y){
    12         if (y&1) (res*=base)%=mod;
    13         (base*=base)%=mod;
    14         y>>=1;
    15     }
    16     return res;
    17 }
    18 void dfs(int x,int fa){
    19     ll num=0;
    20     for (int i=0;i<mp[x].size();i++){
    21         if (mp[x][i]==fa) continue;
    22         dfs(mp[x][i],x);
    23         sz[x]+=sz[mp[x][i]];
    24         ll kk=pow_(2,sz[mp[x][i]]);
    25         (num+=kk-1+mod)%=mod; 
    26     }
    27     sz[x]++;
    28     ll tmp=(pow_(2,sz[x])-1-num+mod)%mod;
    29     (ans+=(1ll*a[x]*tmp))%=mod;
    30 }
    31 
    32 int main(){
    33     int n,x,y;
    34     scanf("%d",&n);
    35     for (int i=1;i<=n;i++) scanf("%d",&a[i]),sz[i]=0;
    36     for (int i=0;i<n-1;i++){
    37         scanf("%d%d",&x,&y);
    38         mp[x].push_back(y);
    39         mp[y].push_back(x);
    40     }
    41     mp[1].push_back(0);
    42     ans=0;
    43     dfs(1,0);
    44     printf("%lld
    ",ans);
    45     return 0;
    46 }
    D

    E.

    题意:用火柴棒拼接小正方形,问拼成n个小正方形所需要的最少木棍数为多少?

    分析:找规律题。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 ll solve(ll n){
     5     ll tmp=sqrt(n);
     6     if (tmp*tmp==n) return (n+tmp)*2;
     7     ll m=(tmp+1)*(tmp+1);
     8     ll len=m-tmp*tmp-1;
     9     ll res=0;
    10     if (tmp*tmp+len/2>=n){
    11         res+=2*(tmp+tmp*tmp);
    12         res+=(n-tmp*tmp)*2+1;
    13     }
    14     else{
    15         res+=2*(tmp+tmp*tmp);
    16         res+=(n-tmp*tmp)*2+2;
    17     }
    18     return res;
    19 }
    20 int main(){
    21     int t; scanf("%d",&t);
    22     ll n;
    23     while (t--){
    24         scanf("%lld",&n);
    25         ll ans=solve(n);
    26         printf("%lld
    ",ans);
    27     }
    28     return 0;
    29 } 
    E

    F.

    题意:已知一张图$dis[n][n]$,其中$dis[i][j]$代表两点之间的“最短路”。重新构建一张新图,问最少保留几条边可以满足两点之间路径最短。

    分析:floyd过程中不断去松弛两点间的最短路,如果可松弛,那么原来存的边就可以不保留。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=310;
     4 const int inf=0xfffffff;
     5 int a[maxn][maxn],vis[maxn][maxn];
     6 int main(){
     7     int n;scanf("%d",&n);
     8     for (int i=1;i<=n;i++)
     9         for (int j=1;j<=n;j++){
    10             scanf("%d",&a[i][j]);
    11             vis[i][j]=1;
    12         }
    13     int ans=0;
    14     for (int i=1;i<=n;i++){
    15         for (int j=1;j<=n;j++){
    16             if (i==j) continue;
    17             for (int k=1;k<=n;k++){
    18                 if (j==k || i==k) continue;
    19                 if (a[i][k]+a[k][j]<=a[i][j]){
    20                     vis[i][j]=0;vis[j][i]=0;
    21                     a[i][j]=a[i][k]+a[k][j];
    22                 }
    23             }
    24         }
    25     } 
    26     for (int i=1;i<=n;i++)
    27         for (int j=1;j<=n;j++) if (!vis[i][j]) ans++;
    28     printf("%d
    ",(n*n-ans-n)/2);
    29     return 0;
    30 } 
    F

    G.

    题意:已知两点$s,e$,有一束光线从s开始指向e,询问是否点$(px,py)$在这束光线上。

    分析:判断点在射线上。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const double eps=1e-10;
     4 int sgn(double x){
     5     if (fabs(x)<eps) return 0;
     6     if (x<0) return -1;
     7     return 1;
     8 }
     9 int main(){
    10     int t; scanf("%d",&t);
    11     double sx,sy,ex,ey,px,py;
    12     while (t--){
    13         scanf("%lf%lf%lf%lf",&sx,&sy,&ex,&ey);
    14         scanf("%lf%lf",&px,&py);
    15         if (sgn(ex-sx)==sgn(sx-px) && sgn(ey-sy)==sgn(sy-py)){
    16             printf("NO
    ");
    17             continue;
    18         }
    19         if (sx==ex){
    20             if (px==sx) printf("YES
    ");
    21             else printf("NO
    ");
    22             continue;
    23         }
    24         if (sy==ey){
    25             if (py==sy) printf("YES
    ");
    26             else printf("NO
    ");
    27             continue;
    28         }
    29         double k=(sy-ey)/(sx-ex);
    30         double b=sy-k*sx;
    31         double tmp=k*px+b;
    32         if (sgn(tmp-py)==0) printf("YES
    ");
    33         else printf("NO
    ");
    34     }
    35     return 0;
    36 } 
    G

    H.

    题意:有n个“up",m个"down",构造一个序列,要求每一点处的"up"数量$geq$"down"数量。同时,还需要挑选k个时间添加背景音乐。询问总的方案数为多少?答案需要%(1e5+3)。

    分析:卡特兰数应用。(我也不知道怎么推。但这个题和hdoj1133基本一样。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int mod=1e5+3;
     4 const int N=1e5+3;
     5 typedef long long ll;
     6 ll fac[N],inv_fac[N];
     7 ll qpow(ll a,ll b){
     8     ll ret=1,tmp=a;
     9     while(b){
    10         if(b&1) (ret*=tmp)%=mod;
    11         b/=2;
    12         (tmp*=tmp)%=mod;
    13     }
    14     return ret;
    15 }
    16 void init(){
    17     fac[0]=1;
    18     for(int i=1;i<N;i++) fac[i]=fac[i-1]*i%mod;
    19     inv_fac[N-1]=qpow(fac[N-1],mod-2);
    20     for(int i=N-2;i>=0;i--) inv_fac[i]=inv_fac[i+1]*(i+1)%mod;
    21 }
    22 ll C(int n,int m){
    23     return (fac[n]*inv_fac[n-m]%mod)*inv_fac[m]%mod;
    24 }
    25 ll Lucas(int n,int m)
    26 {
    27     if(m>n) return 0;
    28     ll ret=1;
    29     while(m>0LL){
    30         ret=(ret*C(n%mod,m%mod))%mod;
    31         m/=mod;
    32         n/=mod;
    33     }   
    34     return ret;
    35 }
    36 int main(){
    37     init();
    38     int n,m,k;scanf("%d%d%d",&n,&m,&k);
    39     int ans=Lucas(n+m,n)-Lucas(n+m,n+1);
    40     ans=1ll*ans*Lucas(n+m,k)%mod;
    41     printf("%d
    ",ans);    
    42     return 0;
    43 }
    H

    I.

    题意:convert all “ig”, “IG” and “Ig” including in the string to “iG”.

    分析:模拟。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int main(){
     4     string s;
     5     cin >> s;
     6     int len=s.size();
     7     for (int i=0;i<len-1;i++){
     8         if ((s[i]=='i' || s[i]=='I') && (s[i+1]=='g' || s[i+1]=='G')){
     9             s[i]='i'; s[i+1]='G';
    10         }
    11     }
    12     cout << s << endl;
    13     return 0;
    14 } 
    I

    J.

    题意:求公式:$[cos^2(frac{(n+1)!+1)}{n}astpi)]$。$2le nle 1e9$

    分析:打表找规律。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 int check(int n){
     5     int kk=sqrt(n);
     6     for(int i=2;i<=kk;i++){
     7         if (n%i==0) return false;
     8     } 
     9     return true;
    10 }
    11 int main(){
    12     int t;scanf("%d",&t);
    13     int n;
    14     while(t--){
    15         scanf("%d",&n);
    16         if (check(n)) printf("1
    ");
    17         else printf("0
    ");
    18     }
    19     return 0;
    20 }
    J
  • 相关阅读:
    《需求规格说明书》的工作流程、组员分工和组员工作量比例
    电子公文传输系统 需求分析
    电子公文传输系统 团队展示
    团队作业(三)
    2.3.1测试
    缓冲区溢出漏洞实验
    cat userlist
    ls的功能
    团队作业(二)——需求分析
    C语言中的函数、数组与指针
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/11168462.html
Copyright © 2020-2023  润新知