• 牛客小白月赛2


    较水题,手速赛。关键是看题不要看错,这样卡时间。还有手速保持在较快的水准,有意识地训练~

    A   数字方阵 > 25663765

    随机化生成方阵,修改直到方阵满足条件 (重复3次,都A了)

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <list>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    #define ll long long
    const long maxn=1e6+5;
    const ll mod=1e9+7;
      
    long a[1005][1005];
    bool vis[100005];
    long n,i,j,sum=0,x,y;
    set<long>f;
     
    bool check()
    {
        f.clear();
        for (i=1;i<=n;i++)
        {
            sum=0;
            for (j=1;j<=n;j++)
                sum+=a[i][j];
            f.insert(sum);
             
            sum=0; 
            for (j=1;j<=n;j++)
                sum+=a[j][i];
            f.insert(sum);
        }
         
        sum=0;
        for (i=1;i<=n;i++)
            sum+=a[i][i];
        f.insert(sum);
     
        sum=0;
        for (i=1;i<=n;i++)
            sum+=a[i][n+1-i];
        f.insert(sum);
         
        if (f.size()!=2*n+2)
            return false;
        else
            return true;
    }
      
    int main()
    {
        long p,q,x,y,temp;
        scanf("%ld",&n);
        while (1)
        {
            sum=0;
            for (i=1;i<=n;i++)
                for (j=1;j<=n;j++)
                {
                    sum++;
                    a[i][j]=sum;
                }
            for (i=1;i<=min(n*n,(long)1000);i++)
            {
                x=rand()%n+1;
                y=rand()%n+1;
                p=rand()%n+1;
                q=rand()%n+1;
                temp=a[x][y];
                a[x][y]=a[p][q];
                a[p][q]=temp;
            }
            if (check())
            {
                for (i=1;i<=n;i++)
                {
                    for (j=1;j<n;j++)
                        printf("%ld ",a[i][j]);
                    printf("%ld
    ",a[i][j]);
                }
                break;
            }
        }
        return 0;
    }

    另:

    对称结构最容易产生相同的行/列/对角线和值

    但对称结构最好创建

    所以创建对称结构,在这基础上进行微调

    A   数字方阵 > 25713373

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <list>
      6 #include <stack>
      7 #include <vector>
      8 #include <set>
      9 #include <map>
     10 #include <queue>
     11 #include <algorithm>
     12 #include <iostream>
     13 using namespace std;
     14 #define ll long long
     15 const long maxn=1e4+5;
     16 const ll mod=1e9+7;
     17 
     18 long a[maxn][maxn];
     19 long i,j,t,n,sum;
     20 set<long>f;
     21  
     22 bool check()
     23 {
     24     f.clear();
     25     for (i=0;i<n;i++)
     26     {
     27         sum=0;
     28         for (j=0;j<n;j++)
     29             sum+=a[i][j];
     30         f.insert(sum);
     31         printf("%ld
    ",sum);
     32          
     33         sum=0; 
     34         for (j=0;j<n;j++)
     35             sum+=a[j][i];
     36         f.insert(sum);
     37         printf("%ld
    ",sum);
     38     }
     39      
     40     sum=0;
     41     for (i=0;i<n;i++)
     42         sum+=a[i][i];
     43     f.insert(sum);
     44     printf("%ld
    ",sum);
     45  
     46     sum=0;
     47     for (i=0;i<n;i++)
     48         sum+=a[i][n+1-i];
     49     f.insert(sum);
     50     printf("%ld
    ",sum);
     51     
     52     if (f.size()!=2*n+2)
     53         return false;
     54     else
     55         return true;
     56 }
     57 
     58 int main()
     59 {
     60     scanf("%ld",&n);
     61     sum=0;
     62     for (i=0;i<n;i++)
     63         for (j=0;j<n-1;j++)
     64         {
     65             sum++;
     66             a[i][j]=sum;
     67         }
     68     for (j=0;j<n;j++)
     69     {
     70         sum++;
     71         a[j][n-1]=sum;
     72     }
     73     /*
     74     for (i=0;i<n;i++)
     75     {
     76         for (j=0;j<n;j++)
     77         {
     78             sum++;
     79             a[i][j]=sum;
     80         }
     81     }
     82     if (n%2==0)
     83     {
     84         t=a[0][n-2];
     85         a[0][n-2]=a[0][n-1];
     86         a[0][n-1]=t;
     87     }
     88     else
     89     {
     90         sum=0;
     91         //
     92     }
     93     */
     94     for (i=0;i<n;i++)
     95     {
     96         for (j=0;j<n;j++)
     97         {
     98             printf("%ld",a[i][j]);
     99             if (j==n-1)
    100                 printf("
    ");
    101             else
    102                 printf(" ");
    103         }
    104     }
    105 //    if (!check())
    106 //        printf("F
    ");
    107     return 0;
    108 }

    B   小马过河 > 25648307

    想不到好方法。做了两条直线(ax+by+c=0),求交点

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <list>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    #define ll long long
    const long maxn=1e6+5;
    const ll mod=1e9+7;
     
    long double xp,yp,xu,yu,xv,yv, x,y;
    long double a1,b1,c1,a2,b2,c2,aa1,bb1,cc1,aa2,bb2,cc2;
     
    int main()
    {
        long t;
        scanf("%ld",&t);
        while (t--)
        {
            scanf("%llf%llf%llf%llf%llf%llf",&xp,&yp,&xu,&yu,&xv,&yv);
            a1=yu-yv;
            b1=xv-xu;
            c1=-a1*xu-b1*yu;
             
            a2=xu-xv;
            b2=yu-yv;
            c2=-a2*xp-b2*yp;
             
            aa1=a1*a2;
            bb1=b1*a2;
            cc1=c1*a2;
             
            aa2=a2*a1;
            bb2=b2*a1;
            cc2=c2*a1;
             
            y=(cc1-cc2)/(bb2-bb1);
            x=(-c1-b1*y)/a1;
             
            printf("%.7llf %.7llf
    ",x,y);
        }
        return 0;
    }

    另:直接推公式

    https://blog.csdn.net/sr_19930829/article/details/19825661

    C   真真假假 > 25645450

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <list>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    #define ll long long
    const long maxn=1e6+5;
    const ll mod=1e9+7;
     
    char str[35][20]={"algorithm", "bitset", "cctype", "cerrno", "clocale",
     "cmath", "complex", "cstdio", "cstdlib", "cstring",
      "ctime", "deque", "exception", "fstream", "functional",
       "limits", "list", "map", "iomanip", "ios",
        "iosfwd", "iostream", "istream", "ostream", "queue",
         "set", "sstream", "stack", "stdexcept", "streambuf",
          "string", "utility", "vector", "cwchar", "cwctype"};
        char s[1000];
     
    void pan()
    {
        long i;
        for (i=0;i<35;i++)
        if (strcmp(s,str[i])==0)
        {
            printf("Qian
    ");
            return;
        }
        printf("Kun
    ");
    }
     
    int main()
    {
        long t;
        scanf("%ld
    ",&t);
        while (t--)
        {
            gets(s);
            pan();
        }
        return 0;
    }

    比赛时候不停“”,太傻,幸好数量不多

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <list>
     6 #include <stack>
     7 #include <vector>
     8 #include <set>
     9 #include <map>
    10 #include <queue>
    11 #include <algorithm>
    12 #include <iostream>
    13 using namespace std;
    14 #define ll long long
    15 const long maxn=1e6+5;
    16 const ll mod=1e9+7;
    17 
    18 
    19 int main()
    20 {
    21     char s[20];
    22     while (scanf("%s",s)!=EOF)
    23     {
    24         s[strlen(s)-1]='';
    25         printf(""%s",",s);
    26     }
    27     return 0;
    28 }

    D   虚虚实实 > 25650110

    看得很懵的题目,这告诫我看完题顺便再看看测试数据

    其实就是求一笔画问题

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <list>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    #define ll long long
    const long maxn=1e6+5;
    const ll mod=1e9+7;
     
    vector<long> p[35];
    bool vis[35];
    long ans,wrong,n,g[35];
     
    void dfs(long d)
    {
        vis[d]=true;
        ans++;
        vector<long>::iterator j;
        for (j=p[d].begin();j!=p[d].end();j++)
            if (!vis[*j])
                dfs(*j);
    }
     
    int main()
    {
        long t,m,i,x,y;
        scanf("%ld",&t);
        while (t--)
        {
            scanf("%ld%ld",&n,&m);
            for (i=1;i<=n;i++)
            {
                p[i].clear();
                vis[i]=false;
                g[i]=0;
            }
            for (i=1;i<=m;i++)
            {
                scanf("%ld%ld",&x,&y);
                g[x]++;
                g[y]++;
                p[y].push_back(x);
                p[x].push_back(y);
            }
            ans=0;
            dfs(1);
             
            wrong=0;
            for (i=1;i<=n;i++)
                if (g[i]%2==1)
                    wrong++;
     
            if (ans==n && wrong<=2)
                printf("Zhen
    ");
            else
                printf("Xun
    ");
        }
        return 0;
    }

    E   是是非非 > 25653790

    nim问题。好像有升级版https://blog.csdn.net/acm_baihuzi/article/details/41622825

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <list>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    #define ll long long
    const long maxn=1e5+5;
    const ll mod=1e9+7;
     
    long a[maxn];
     
    int main()
    {
        long n,t,v,x,y,i;
        scanf("%ld%ld",&n,&t);
        v=0;
        for (i=1;i<=n;i++)
        {
            scanf("%ld",&a[i]);
            v=v ^ a[i];
        }
        while (t--)
        {
            scanf("%ld%ld",&x,&y);
            v=v ^ a[x];
            a[x]=y;
            v=v ^ a[x];
            if (v==0)
                printf("Li
    ");
            else
                printf("Kan
    ");
        }
        return 0;
    }

    F   黑黑白白 > 25653038

    树上的博弈论。从叶子到根。

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <list>
     6 #include <stack>
     7 #include <vector>
     8 #include <set>
     9 #include <map>
    10 #include <queue>
    11 #include <algorithm>
    12 #include <iostream>
    13 using namespace std;
    14 #define ll long long
    15 const long maxn=1e4+5;
    16 const ll mod=1e9+7;
    17   
    18 vector<long> p[maxn];
    19 bool vis[maxn],v[maxn][2];
    20 long fa[maxn];
    21   
    22 void dfs(long d)
    23 {
    24     vis[d]=true;
    25     vector<long>::iterator j;
    26     bool leap=true;
    27     for (j=p[d].begin();j!=p[d].end();j++)
    28         if (!vis[*j])
    29         {
    30             dfs(*j);
    31             leap=false;
    32         }
    33         else
    34             fa[d]=*j;
    35     if (leap)
    36     {
    37         v[d][0]=true;   //oven step
    38         v[d][1]=false;  //odd
    39     }
    40     else
    41     {
    42         v[d][0]=false;  //oven step
    43         v[d][1]=false;  //odd      
    44         for (j=p[d].begin();j!=p[d].end();j++)
    45             if (fa[d]!=*j)
    46             {
    47                 if (!v[*j][1])
    48                     v[d][1]=true;
    49                 if (!v[*j][0])
    50                     v[d][0]=true;
    51             }      
    52     }
    53 }
    54   
    55 int main()
    56 {
    57     long t,n,m,i,x,y,r;
    58     scanf("%ld",&t);
    59     while (t--)
    60     {
    61         scanf("%ld%ld",&n,&r);
    62         for (i=1;i<=n;i++)
    63         {
    64             p[i].clear();
    65             vis[i]=false;
    66         }
    67         for (i=1;i<n;i++)
    68         {
    69             scanf("%ld%ld",&x,&y);
    70             p[y].push_back(x);
    71             p[x].push_back(y);
    72         }
    73         fa[r]=r;
    74         dfs(r);
    75          
    76         if (v[r][1])
    77             printf("Gen
    ");
    78         else
    79             printf("Dui
    ");
    80     }
    81     return 0;
    82 }

    G   文 > 25646203

    只用保存最大的状态。

    选择题答卷用char输入,一一比对会快一点

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <list>
     6 #include <stack>
     7 #include <vector>
     8 #include <set>
     9 #include <map>
    10 #include <queue>
    11 #include <algorithm>
    12 #include <iostream>
    13 using namespace std;
    14 #define ll long long
    15 const long maxn=1e6+5;
    16 const ll mod=1e9+7;
    17  
    18 char answer[100005],name[100],maxname[100];
    19  
    20 int main()
    21 {
    22     long n,m,maxr,r,i,j;
    23     char c;
    24     scanf("%ld%ld",&n,&m);
    25     scanf("%s",answer);
    26     maxr=-1;
    27     strcpy(name,"");
    28     for (i=1;i<=m;i++)
    29     {
    30         scanf("%s
    ",name);
    31         r=0;
    32         for (j=0;j<n;j++)
    33         {
    34             scanf("%c",&c);
    35             if (c==answer[j])
    36                 r++;
    37         }
    38         if (r>maxr || (r==maxr && strcmp(name,maxname)<0))
    39         {
    40             maxr=r;
    41             strcpy(maxname,name);
    42         }
    43     }
    44     printf("%s
    ",maxname);
    45     printf("%.2lf
    ",100.0*maxr/n);
    46     return 0;
    47 }

    H   武 >  25713562

    求最短路,从s点出发的第k小距离

    priority_queue里的符号老是写反……

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <list>
     6 #include <stack>
     7 #include <vector>
     8 #include <set>
     9 #include <map>
    10 #include <queue>
    11 #include <algorithm>
    12 #include <iostream>
    13 using namespace std;
    14 #define ll long long
    15 const long maxn=1e5+5;
    16 const ll mod=1e9+7;
    17 #define inf 1e9
    18 vector<pair<long,long> > p[maxn];
    19 long dist[maxn];
    20 bool vis[maxn];
    21   
    22 struct cmp
    23 {
    24     bool operator() (int a,int b)
    25     {
    26         return dist[a]>dist[b];  //opposite
    27     }
    28 };
    29   
    30 priority_queue<int,vector<int>,cmp> f;
    31   
    32 int main()
    33 {
    34     long n,d,k,i,x,y,z;
    35     vector<pair<long,long> >::iterator j;
    36     scanf("%ld%ld%ld",&n,&d,&k);
    37     for (i=1;i<=n;i++)
    38     {
    39         p[i].clear();
    40         dist[i]=inf;
    41         vis[i]=false;
    42     }
    43     dist[d]=0;
    44       
    45     for (i=1;i<n;i++)
    46     {
    47         scanf("%ld%ld%ld",&x,&y,&z);
    48         p[x].push_back(make_pair(y,z));
    49         p[y].push_back(make_pair(x,z));
    50     }
    51     f.push(d);
    52      
    53     for (i=1;i<=k+1;i++)
    54     {
    55         while (vis[f.top()])
    56             f.pop();
    57         d=f.top();
    58         vis[d]=true;
    59         f.pop();
    60         for (j=p[d].begin();j!=p[d].end();j++)
    61             if (!vis[j->first] && dist[j->first]>dist[d]+j->second)
    62             {
    63                 dist[j->first] = dist[d]+j->second;
    64                 f.push(j->first);
    65             }
    66     }
    67     printf("%ld",dist[d]);
    68     return 0;
    69 }

    另: 树结构,根到某个节点的路径和路径长度唯一确定

    可以优化,不过像题解说的O(n)是不可能的,如所有点仅与根节点相连

     H   武 > 25713622

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <list>
     6 #include <stack>
     7 #include <vector>
     8 #include <set>
     9 #include <map>
    10 #include <queue>
    11 #include <algorithm>
    12 #include <iostream>
    13 using namespace std;
    14 #define ll long long
    15 const long maxn=1e5+5;
    16 const ll mod=1e9+7;
    17 #define inf 1e9
    18 vector<pair<long,long> > p[maxn];
    19 long dist[maxn];
    20 bool vis[maxn];
    21   
    22 struct cmp
    23 {
    24     bool operator() (int a,int b)
    25     {
    26         return dist[a]>dist[b];  //opposite
    27     }
    28 };
    29   
    30 priority_queue<int,vector<int>,cmp> f;
    31   
    32 int main()
    33 {
    34     long n,d,k,i,x,y,z;
    35     vector<pair<long,long> >::iterator j;
    36     scanf("%ld%ld%ld",&n,&d,&k);
    37     for (i=1;i<=n;i++)
    38     {
    39         p[i].clear();
    40         dist[i]=inf;
    41         vis[i]=false;
    42     }
    43     dist[d]=0;
    44       
    45     for (i=1;i<n;i++)
    46     {
    47         scanf("%ld%ld%ld",&x,&y,&z);
    48         p[x].push_back(make_pair(y,z));
    49         p[y].push_back(make_pair(x,z));
    50     }
    51     f.push(d);
    52      
    53     for (i=1;i<=k+1;i++)
    54     {
    55         d=f.top();
    56         vis[d]=true;
    57         f.pop();
    58         for (j=p[d].begin();j!=p[d].end();j++)
    59             if (!vis[j->first])
    60             {
    61                 dist[j->first] = dist[d]+j->second;
    62                 f.push(j->first);
    63             }
    64     }
    65     printf("%ld",dist[d]);
    66     return 0;
    67 }

    I   艺 > 25665565

    取每个节目的开始时间和  最后结束时间,时间从小到大,在某一个时间内,两个电视分别播一个特定的节目,取最大值,若最大值小于0,不取,否则取。

    调了很久,最后发现sort的变量写错了(n->m),看来程序写错了也不行一昧地调试,重新看一遍代码,会发现调试难以发现的错误……

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <list>
     6 #include <stack>
     7 #include <vector>
     8 #include <set>
     9 #include <map>
    10 #include <queue>
    11 #include <algorithm>
    12 #include <iostream>
    13 using namespace std;
    14 #define ll long long
    15 const long maxn=1e5+5;
    16 const ll mod=1e9+7;
    17 #define inf 1e9
    18  
    19 struct node
    20 {
    21     long long x,v;
    22 }f1[maxn],f2[maxn];
    23  
    24 bool cmp(node a,node b)
    25 {
    26     return a.x<b.x;
    27 }
    28  
    29 int main()
    30 {
    31     long n,m,t,i,j,a,b;
    32     long long ans=0,v,x,prex;
    33     scanf("%ld%ld%ld",&n,&m,&t);
    34      
    35     for (i=1;i<=n;i++)
    36         scanf("%lld%lld",&f1[i].x,&f1[i].v);
    37     sort(f1+1,f1+n+1,cmp);
    38     f1[n+1].x=t; f1[n+1].v=0; n++;
    39     f1[n+2].x=inf;
    40          
    41     for (i=1;i<=m;i++)
    42         scanf("%lld%lld",&f2[i].x,&f2[i].v);
    43     sort(f2+1,f2+m+1,cmp);
    44     f2[m+1].x=t; f2[m+1].v=0; m++;
    45     f2[m+2].x=inf;
    46      
    47     a=1; b=1; x=0; i=1; j=1;
    48     while (a<=n || b<=m)
    49     {
    50         //one+two pointers
    51          
    52         //find next time
    53         prex=x;
    54         if (f1[a].x<f2[b].x)
    55         {
    56             x=f1[a].x;
    57             a++;
    58         }
    59         else if (f1[a].x>f2[b].x)
    60         {
    61             x=f2[b].x;
    62             b++;
    63         }
    64         else
    65         {
    66             x=f1[a].x;
    67             a++;
    68             b++;
    69         }
    70          
    71         //find the value that is smaller that x, whose program can be watches at time x
    72         while (f1[i+1].x<x)
    73             i++;
    74         while (f2[j+1].x<x)
    75             j++;
    76          
    77         v=max(f1[i].v,f2[j].v);
    78         if (v>0)
    79             ans+=(x-prex)*v;
    80     }
    81     printf("%lld
    ",ans);
    82     return 0;
    83 }
    84 /*
    85 1 2 5
    86 0 3
    87 0 1
    88 2 5
    89 25
    90 */

    J   美 > 25656447

    贪心。排序后(a[1],a[2],…,a[n]从小到大),a[1] -> a[n] th -> a[2] th -> a[n-1] th -> ……

    比赛时没证明就直接写了,发现对了,感觉。。。

    证明:

     

    环结构,每个数Ri都重复计算了两遍,去掉绝对值,2*n次计算中,n次减,n次加。要想值最大,则大值尽量地加,小值尽量地减。

    即a[1]~a[n/2]减两次;a[(n+1)/2+1]~a[n]加两次。如果n为奇数,则a[n/2+1]加一次,减一次。

     a[1] -> a[n] th -> a[2] th -> a[n-1] th -> ……正好满足条件,得证。

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <list>
     6 #include <stack>
     7 #include <vector>
     8 #include <set>
     9 #include <map>
    10 #include <queue>
    11 #include <algorithm>
    12 #include <iostream>
    13 using namespace std;
    14 #define ll long long
    15 const long maxn=1e5+5;
    16 const ll mod=1e9+7;
    17  
    18 long long a[maxn],b[maxn];
    19  
    20 int main()
    21 {
    22     long n,i,x,y;
    23     long long ans=0;
    24     scanf("%ld",&n);
    25     for (i=1;i<=n;i++)
    26     {
    27         scanf("%lld",&a[i]);
    28     }
    29     sort(a+1,a+n+1);
    30      
    31     x=1;
    32     y=n;
    33     for (i=1;i<=n;i++)
    34     {
    35         if (i%2==0)
    36         {
    37             b[i]=a[x];
    38             x++;
    39         }
    40         else
    41         {
    42             b[i]=a[y];
    43             y--;
    44         }
    45     }
    46      
    47     ans=0;
    48     for (i=2;i<=n;i++)
    49         ans+=abs(b[i]-b[i-1]);
    50     ans+=abs(b[n]-b[1]);
    51      
    52     printf("%lld
    ",ans);
    53     return 0;
    54 }
  • 相关阅读:
    D. Time to Run【构造】
    P3388 割顶 【求割点个数】
    处女座的测验 素数,构造
    处女座与复读机 DP
    求一个分数小数点后指定位数的数字
    安卓开发创建活动,布局,添加按钮,she使用Toast,设菜单,使菜单相关联等操作
    三进制 处女座的砝码 高精度
    上海高校程序设计联赛 D-CSL的字符串 栈模拟
    区间DP经典 石子合并
    区间DP 洛谷P2858牛奶零食
  • 原文地址:https://www.cnblogs.com/cmyg/p/8906316.html
Copyright © 2020-2023  润新知