• Codeforces Round #417 (Div. 2)


    昨天打了场cf,只做出第一道水题,而和我同级的队员都做出三道题,有点难过,落下太多,剩下的唯有好好补题。

    Sagheer, the Hausmeister

    昨天比赛时候写的BFS,到最后不好对上面有没有进行判断。

    今天早上花一个半小时软磨硬泡出来的DFS

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 int n,m;
      4 char temp[16][105];
      5 int maze[16][105];
      6 int l[16];
      7 int r[16];
      8 const int inf = 0x3f3f3f3f;
      9 int dfs(int curfloor,int stairs)
     10 {
     11     if(curfloor>=n-1)
     12     {
     13         if(l[n-1]==inf)
     14         {
     15             return 0;
     16         }
     17         else
     18         {
     19             if(!stairs)
     20             {
     21                 return r[n-1] + 1; //末尾加1上1台阶
     22             }
     23             else
     24             {
     25                 return m - 1 - l[n-1] + 1;
     26             }
     27         }
     28     }
     29     if(l[curfloor]==inf)    //本楼道没有灯亮,就不用走了
     30     {
     31         int cost = dfs(curfloor+1,stairs);
     32         if(cost)
     33         {
     34             return cost+1;
     35         }
     36         else
     37         {
     38             return cost;
     39         }
     40     }
     41     else                       //有灯则继续考虑
     42     {
     43         int same = dfs(curfloor+1,stairs);              //先往上走走试试
     44         int different = dfs(curfloor+1,!stairs);
     45         int cost = 0;
     46         if(!stairs)  //0表示我是从下一层从左上来的
     47         {
     48             cost = same+r[curfloor]*(same>0?2:1)+1; //如果以后没有,我就停在最后的位置,不用绕回来了
     49             cost = min(cost,different+r[curfloor]+(m-1-r[curfloor])*(different>0?1:0)+1); //+1表示上到现在的台阶
     50         }
     51         else    //从右上
     52         {
     53             cost = same+(m-1-l[curfloor])*(same>0?2:1)+1;
     54             cost = min(cost,different+m-1-l[curfloor]+l[curfloor]*(different>0?1:0)+1);
     55         }
     56         return cost;
     57     }
     58 }
     59 int main()
     60 {
     61     cin>>n>>m;
     62     m += 2;
     63     for(int i=0;i<n;i++)
     64     {
     65         cin>>temp[i];
     66     }
     67     int v = n-1;
     68     memset(l,inf,sizeof(l));
     69     memset(r,0,sizeof(r));
     70     for(int i=0;i<n;i++)
     71     {
     72         for(int j=0;j<m;j++)
     73         {
     74             maze[i][j] = temp[v][j]-'0';
     75             if(maze[i][j]==1)
     76             {
     77                 l[i] = min(l[i],j);
     78                 r[i] = max(r[i],j);
     79             }
     80         }
     81         v--;
     82     }
     83     int cost = dfs(0,0);
     84     if(cost>0)
     85     {
     86         cout<<cost-1<<endl;
     87     }
     88     else
     89     {
     90         cout<<0<<endl;
     91     }
     92     return 0;
     93 }
     94 /*
     95 4 3
     96 00000
     97 00100
     98 00000
     99 00000
    100 */
    DFS

     膜一下Q老师的DFS,从上往下扫,up和 if(!flag)l[i]=m+1,r[i]=0 省去了大量代码。

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    char s[25][155];
    int n,m,res,l[25],r[25];
    void dfs(int dep,int up,int lr,int now)
    {
        if(dep==up)
        {
            if(lr==0)res=min(res,now+r[dep]);
            else res=min(res,now+m+1-l[dep]);
            return;
        }
        dfs(dep-1,up,lr^1,now+m+2);
        if(lr==0)dfs(dep-1,up,lr,now+2*r[dep]+1);
        else dfs(dep-1,up,lr,now+2*(m+1-l[dep])+1);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);
        int up=-1;
        for(int i=0;i<n;i++)
        {
            bool flag=0;
            for(int j=0;j<m+2;j++)
                if(s[i][j]=='1')r[i]=j,flag=1;
            for(int j=m+1;j>=0;j--)
                if(s[i][j]=='1')l[i]=j,flag=1;
            if(flag && up<0)up=i;
            if(!flag)l[i]=m+1,r[i]=0;
        }
        if(up<0)return 0*printf("0");
        res=n*(m+2);
        dfs(n-1,up,0,0);
        return 0*printf("%d",res);
    }
    qls

    Sagheer and Nubian Market

    二分满足我们要求的最大K. + sort ,复杂度 nlog2n

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 1e5+5;
     4 typedef long long ll;
     5 ll arr[maxn];
     6 ll res[maxn];
     7 int main()
     8 {
     9     ll n,S;
    10     cin>>n>>S;
    11     for(int i=1;i<=n;i++)
    12     {
    13         cin>>arr[i];
    14     }
    15     //枚举k
    16     ll l = 1,r = n,mid = 0;
    17     int k = 0,T = 0;
    18     while(l<=r)
    19     {
    20         mid = (r-l)/2+l;
    21         for(int i=1;i<=n;i++)
    22         {
    23             res[i] = arr[i] + i*mid;
    24         }
    25         sort(res+1,res+n+1);
    26         ll sum = 0;
    27         for(int i=1;i<=mid;i++)
    28         {
    29             sum += res[i];
    30         }
    31         if(sum<=S)
    32         {
    33             k = mid;
    34             T = sum;
    35             l = mid+1;
    36         }
    37         else
    38         {
    39             r = mid-1;
    40         }
    41     }
    42     cout<<k<<" "<<T<<endl;
    43     return 0;
    44 }
    Code

    Sagheer and Apple Tree

    初次接触Nim博弈。

    有a1,a2,a3,,,,an堆石子,如果s = a1^a2^a3^...^an = 0,那么就是后手赢,否则先手赢。

    其实挺好理解的,比如1 4 5,二进制是1,100,101,每个位置的1都是成对出现,那么先手怎么取后手重复就行啦。

    本题变了下形。 底部设为蓝色节点,蓝色节点的父亲节点设为红色节点。红色节点的父亲节点设为蓝色节点,以此类推。

    我们只需要判断蓝色节点的异或是否=0就可以了。因为先手只要一挪动红色节点上的苹果,我们就从蓝色节点上拿掉相应的苹果就可以了。

    1.s = 0,我们交换红色之间的,蓝色之间的,红色和蓝色相等的数量的。

    2.s!=0,我们设红色节点为num1,蓝色为num2.s^num1^num2=0就可以啦。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 1e5+5;
     4 typedef long long ll;
     5 map<int,int>blue;
     6 map<int,int>red;
     7 int arr[maxn];
     8 vector<int> son[maxn];
     9 int s = 0;
    10 ll bluenum = 0;
    11 ll rednum = 0;
    12 int DFS(int u)
    13 {
    14     int t = son[u].size();
    15    if(!t)           //统计叶子节点的个数
    16    {
    17        blue[arr[u]]++;
    18        bluenum++;
    19        s ^= arr[u];
    20        return 1;
    21    }
    22    int ans = 0;
    23    for(int i=0;i<t;i++)
    24    {
    25        ans = DFS(son[u][i]);
    26    }
    27    if(ans)          //统计red节点的个数
    28    {
    29        rednum++;
    30        red[arr[u]]++;
    31    }
    32    else
    33    {
    34        s ^= arr[u];
    35        blue[arr[u]]++;
    36        bluenum++;
    37    }
    38    return !ans;
    39 }
    40 int main()
    41 {
    42     int n;
    43     cin>>n;
    44     for(int i=1;i<=n;i++) cin>>arr[i];
    45     for(int i=2;i<=n;i++)
    46     {
    47         int x;
    48         cin>>x;
    49         son[x].push_back(i);
    50     }
    51     DFS(1);
    52     ll sum = 0;
    53     if(s==0)
    54     {
    55         sum += bluenum*(bluenum-1LL)/2LL+rednum*(rednum-1LL)/2LL;
    56         for(map<int,int>::iterator blueit = blue.begin();blueit!=blue.end();blueit++)
    57         {
    58             int num = blueit->first;
    59             if(red.count(num))
    60             {
    61                 sum += (ll)blueit->second*(ll)(red[num]);
    62             }
    63         }
    64     }
    65     else
    66     {
    67         for(map<int,int>::iterator blueit = blue.begin();blueit!=blue.end();blueit++)
    68         {
    69             int num1 = blueit->first;
    70             int num2 = s^num1;
    71             if(red.count(num2))
    72             {
    73                 sum += (ll)blue[num1]*(ll)red[num2];
    74             }
    75         }
    76     }
    77     cout<<sum<<endl;
    78     return 0;
    79 }
    Code
  • 相关阅读:
    IT小小鸟读书笔记2
    第五周读书笔记
    JSON Schema 入门指南【Java后端使用】
    win10装多个MySQL(MySQL 8.0免安装版)
    记一些实习生问我的问题
    JAVA项目(maven)使用钉钉SDK(获取token、用户等)
    从项目开始的前端开发学习
    从项目开始的Java开发学习
    HBuilderX 5+APP MUI 入门
    项目部署各种配置
  • 原文地址:https://www.cnblogs.com/littlepear/p/6932184.html
Copyright © 2020-2023  润新知