zoukankan      html  css  js  c++  java
  • 小白月赛6-题解整理

    A-典型的追击问题,较多的坑点,回游有很多种情况,注意分类

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    int main(){
      double l,k,a,b;
      cin>>l>>k>>a>>b;
      printf("%.2f
    ",l/b-l/a);
      return 0;
    }
    View Code

    B-水题,模拟就行

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    int a[1000006];
    int main(){
      int n;
      while(~scanf("%d",&n)){
        for (int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        int flag=2;
        int cnt=0;
        for (int i=1;i<n;i++){
            if (flag==2){
                if (a[i]<a[i+1]){
                    flag=1;
                }
                if (a[i]>a[i+1]){
                    flag=3;
                }
                continue;
            }
            if( flag==1 &&a[i]>a[i+1]){
                flag=3;
                cnt++;
                continue;
            }
            if ( flag==3 && a[i]<a[i+1]){
                flag=1;
                continue;
            }
        }
        printf("%d
    ",cnt);
      }
      return 0;
    }
    View Code

    C-典型的树的直径问题-两遍DFS

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define INF 1e9+7
    using namespace std;
    const int MAXN = 2000000;
    const int MAXM = 2000000;
    int n,m;
    struct EDGE
    {
        int v,next,w;
    }edge[MAXN];
    int head[MAXN],e;
    int q[MAXN],vis[MAXN],d[MAXN];
    void init()
    {
        e=0;
        memset(head,-1,sizeof(head));
    }
    void add(int u,int v,int w)//链式前向星部分
    {
        edge[e].v=v;
        edge[e].w=w;//权重
        edge[e].next=head[u];//下一条边
        head[u]=e++;//u为节点边的头节点
    }
    void bfs(int src)
    {
        for(int i=1;i<=n;i++)vis[i]=0,d[i]=INF;
        int h=0,t=0;
        q[t++]=src;
        vis[src]=1;
        d[src]=0;
        while(h<t)
        {
            int u=q[h++];
            for (int i=head[u];i!=-1;i=edge[i].next)
            {
                int v = edge[i].v;
                int w = edge[i].w;
                if (d[u]+w<d[v]){
                    d[v]=d[u]+w;
                    if (!vis[v])
                    {
                        q[t++]=v;
                        vis[v]=1;
                    }
                }
            }
        }
    }
    int main(){
     int u,v,w;
     char k;
     scanf("%d",&n);
     init();
     for(int i=1;i<=n-1;i++)
     {
         scanf("%d%d",&u,&v);
         add(u,v,1);
         add(v,u,1);
     }
     bfs(1);
     int pos=-1,mx=-1;
     for (int i=1;i<=n;i++)
        if (d[i]>mx)
     {
         mx=d[i];
         pos=i;
     }
     bfs(pos);
     mx=-1;
     for (int i=1;i<=n;i++)
        if (d[i]>mx)mx=d[i];
     printf("%d
    ",mx+1);
     return 0;
    }
    View Code

    D-水题

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<vector>
    #include<map>
    using namespace std;
    char a[1000006];
    int pre[1000006];
    int main(){
      int n,m;
      map<char,int> p;
      while(~scanf("%d%d",&n,&m)){
        p.clear();
        scanf("%s",a);
        int lena=strlen(a);
        for (int i=0;i<lena;i++){
           p[a[i]]++;
           pre[i+1]=p[a[i]];
        }
        int tmp;
        for (int i=1;i<=m;i++){
            scanf("%d",&tmp);
            printf("%d
    ",pre[tmp]);
        }
      }
      return 0;
    }
    View Code

    E-很好的简单搜索

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #define rep(i,j,k) for(int i=j;i<=k;++i)
    using namespace std;
    int vis[1005][1005];
    int dx[10]={0,0,1,-1,1,-1,1,-1};
    int dy[10]={1,-1,0,0,1,-1,-1,1};
    int n,m;
    bool dfs(int x,int y,int z){
        vis[x][y]=z;
        int xx,yy;
        int cnt;
        for (int i=0;i<=7;i++){
            xx=x;
            yy=y;
            if(i%2==0)
            cnt=1;
            for (int j=0;j<=3;j++){
               xx=xx+dx[i];
               yy=yy+dy[i];
            //   cout<<xx<<" "<<yy<<" ";
               if (xx<1 || yy<1 || xx>n || yy>n || vis[xx][yy]!=z){
                break;
               }
               cnt++;
            }
            if (cnt>=5){
                return 1;
            }
        }
        return 0;
    }
    int main()
        {
     
            while(~scanf("%d %d",&n,&m))
            {
     memset(vis,-1,sizeof(vis));
            int id=-1,x,y;
            rep(i,1,m)
            {
                scanf("%d %d",&x,&y);
                if(id==-1)
                {
                    if(dfs(x,y,i%2))
                        id=i;
                }
            }
             if(id==-1)
                printf("UNK %d
    ",m);
            else if(id%2)
                printf("HtBest %d
    ",id);
            else
                printf("WHZ %d
    ",id);
            }
            return 0;
        }
    View Code

    F-树状数组,把维护区间和改为维护区间乘积就行

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    int dx[10]={1,-1,1,-1,0,0,-1,1};
    int dy[10]={1,-1,0,0,-1,1,1,-1};
    int vis[1004][1004];
    int n,m;
    bool dfs(int x,int y,int z){
       vis[x][y]=z;
       int xx,yy,cnt;
       for (int i=0;i<=7;i++){
          xx=x;
          yy=y;
          if (i%2==0){
            cnt=1;
          }
          for(int j=0;j<=3;j++){
             xx+=dx[i];
             yy+=dy[i];
             if (xx<1 || yy<1 || xx>n || yy>n || vis[xx][yy]!=z){
                break;
             }
             cnt++;
          }
          if (cnt>=5){
            return 1;
          }
       }
       return 0;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m)){
            int x,y;
            int flag=-1;
            memset(vis,-1,sizeof(vis));
            for (int i=1;i<=m;i++){
               scanf("%d%d",&x,&y);
               if (flag==-1){
                  if (dfs(x,y,i%2)){
                      flag=i;
                  }
               }
            }
            if (flag==-1){
                printf("UNK %d
    ",m);
            }else if (flag%2==0){
                printf("WHZ %d
    ",flag);
            }else if (flag%2==1){
                printf("HtBest %d
    ",flag);
            }
        }
        return 0;
    }
    View Code

    G-重载set内部排序就行

    #include<bits/stdc++.h>
    using namespace std;
    int m,k;
    struct cmp
    {
        bool operator() (int a,int b)
        {
            if(abs(a-b)<=k) return false;
            return a<b;
        }
    };
    set<int,cmp>s;
    int main()
    {
        scanf("%d%d",&m,&k);
        int x;
        char op[8];
        while(m--)
        {
            scanf("%s%d",op,&x);
            if(op[0]=='a')
            {
                if(s.find(x)==s.end())
                {
                    s.insert(x);
                }
            }
            else if(op[0]=='d')
            {
                s.erase(x);
            }
            else
            {
                if(s.find(x)!=s.end()) printf("Yes
    ");
                else printf("No
    ");
            }
        }
        return 0;
    }
    View Code

    H-裸题最小生成树

    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    struct node{
      int u,v,w;
    }a[500006];
    int p[100006];
    int r[100006];
    int n,m;
    int find(int x){return p[x] == x ? x : p[x] = find(p[x]);}//不是根节点
    int cmp(node x,node y)
    {
        return x.w<y.w;
    }
    int Kruskal(){
            int ans=0;
            int num=0;
            for (int i=1; i<=n; i++)p[i]=i;
            sort(a+1,a+1+m,cmp);
            for (int i=1; i<=m; i++)
            {
                int x=find(a[i].u);//出发点的根节点
                int y=find(a[i].v);//到达点的根节点
                if (x!=y)//不是一个根节点
                {
                    ans+=a[i].w;//连接
                    p[x]=y;//y是x的父亲节点
                    num++;//建立好了n-1条边
                }
                if (num==n-1){
                    break;
                }
            }
        return ans;
    }
    int main()
    {
        int tmp1,tmp2,tmp3;
        while(~scanf("%d%d",&n,&m))
        {
            for (int i=1; i<=m; i++)
            {
                scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
            }
            printf("%d
    ",Kruskal());
        }
        return 0;
    }
    View Code

    I-裸的最短路问题

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int a[1005][1005];//邻接表点
    ll d[1005];//到出发点距离
    int vis[10005];//是否访问过
    int n,m,s,t;
    void Dijkstra(int st)
    {
        int minn;//最小值
        int p;//
        for (int i=1; i<=n; i++)d[i]=a[st][i];//初始化 每个点到出发点的距离
        vis[st]=1;
        d[st]=0;
        for (int i=1; i<=n-1; i++)
        {
            minn=INF;
            for (int j=1; j<=n; j++)
                if (!vis[j] && minn>d[j]) //如果未被访问过 并且到目前点的距离比min更小
                {
                    p=j;//更新边
                    minn=d[j];//更新新的距离
                }
                //循环下来 我们找到了最小的一条边
            vis[p]=1;//走过
            for (int j=1; j<=n; j++)
            {
                if (!vis[j] && d[p]+a[p][j]<d[j])
                    d[j]=d[p]+a[p][j];
            }
        }
        if (d[t]!=INF)
            printf("%d
    ",d[t]);
        else
            printf("-1
    ");
    }
      
    int main()
    {
        int tmp1,tmp2,tmp3;
        while (~scanf("%d%d%d%d",&n,&m,&s,&t))
        {
            memset(vis,0,sizeof(vis));
            memset(a,0x3f,sizeof(a));
            for (int i=0; i<m; i++)
            {
                scanf("%d%d%d",&tmp1,&tmp2,&tmp3);
                if (tmp3<a[tmp1][tmp2]){
                a[tmp1][tmp2]=tmp3;
                a[tmp2][tmp1]=tmp3;
                }
            }
            Dijkstra(s);
        }
        return 0;
    }
    View Code

    J-一阶线性递推+逆元/矩阵快速幂

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #define ll long long
    using namespace std;;
    const ll mod = 1e9+7;
    ll pow(ll a,ll b)
    {
        ll ans = 1;
        while(b)
        {
            if (b&1)
            {
                ans = ans*a%mod;
            }
            a = a*a%mod;
            b/=2;
        }
        return ans;
    }
    int main()
    {
        ios::sync_with_stdio(0);
        ll n,k,p;
        ll ans=0;
        while(~scanf("%lld%lld%lld",&n,&k,&p))
        {
            if (k==1)
            {
                 ans=(n*(n-1)%mod/2*p+n)%mod;
                 printf("%lld
    ",ans);
            }
            else
            {
                ll inv=pow(k-1,mod-2);
                ans=(1+p*inv%mod)%mod*((pow(k,n)-1+mod)%mod)%mod*inv%mod;
                ans=(ans-p*inv%mod*n%mod+mod)%mod;
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
    View Code
    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    hdoj 4251 The Famous ICPC Team Again
    hdoj 1879 最小生成树之继续畅通工程
    并查集之Dragon Balls
    并查集之 Is It A Tree?
    hdoj 1874最短路之畅通工程续
    1040: Count
    hdoj 1874最短路之最短路径问题
    并查集之小希的迷宫
    并查集之食物链
    Ordered Fractions
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/9525988.html
Copyright © 2011-2022 走看看