• AtCoder Beginner Contest 190


    传送门:https://atcoder.jp/contests/abc190

    A:

    Takahashi和Aoki分别有A和B颗糖果,两人轮流吃一个,若C为0则Takahashi先吃,C为1则Aoki先吃,先吃完的为输。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <vector>
     7 #include <map>
     8 #include <cstdlib>
     9 #include <cstring>
    10 #include <cmath>
    11 typedef long long ll;
    12 const int INF=0x3f3f3f3f;
    13 using namespace std;
    14 int a,b,c;
    15 int main(void)
    16 {
    17     cin>>a>>b>>c;
    18     if(c==0)
    19     {
    20         if(a>b)cout<<"Takahashi"<<endl;
    21         else cout<<"Aoki"<<endl;
    22     }
    23     else
    24     {
    25         if(a<b)cout<<"Aoki"<<endl;
    26         else cout<<"Takahashi"<<endl;
    27     }
    28     return 0;
    29 }

    B:

    Takahashi有N段符咒,每段需要吟唱Xi秒,伤害为Yi,而怪兽能免疫吟唱时间在S秒及以上和伤害在D及以下的符咒,问能否对怪兽造成伤害。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <vector>
     7 #include <map>
     8 #include <cstdlib>
     9 #include <cstring>
    10 #include <cmath>
    11 typedef long long ll;
    12 const int INF=0x3f3f3f3f;
    13 using namespace std;
    14 int n,s,d;
    15 int main(void)
    16 {
    17     cin>>n>>s>>d;
    18     while(n--)
    19     {
    20         int x,y;
    21         cin>>x>>y;
    22         if(x>=s||y<=d)continue;
    23         cout<<"Yes"<<endl;
    24         return 0;
    25     }
    26     cout<<"No"<<endl;
    27     return 0;
    28 }

    C:

    有N个盘子和M个状态,第i个状态满足当且仅当第Ai和第Bi个盘子上有一个以上的球。有K个人,每个人可以把一个球放在第Ci或者第Di个盘子上。求能满足的最多状态数。

    分析:由于K<=16,那么总的情况数只有216种,因此可以直接暴搜,每次更新答案即可。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <vector>
     7 #include <map>
     8 #include <cstdlib>
     9 #include <cstring>
    10 #include <cmath>
    11 typedef long long ll;
    12 const int INF=0x3f3f3f3f;
    13 using namespace std;
    14 int n,m,a[1000][2],b[1100],c[1000][2],k,ans;
    15 void dfs(int t)
    16 {
    17     if(t==k+1)
    18     {
    19         int cnt=0;
    20         for(int i=1;i<=m;++i)
    21         {
    22             if(b[a[i][0]]&&b[a[i][1]])cnt++;
    23         }
    24         ans=max(cnt,ans);
    25     }
    26     else
    27     {
    28         b[c[t][0]]++;
    29         dfs(t+1);
    30         b[c[t][0]]--;
    31         b[c[t][1]]++;
    32         dfs(t+1);
    33         b[c[t][1]]--;
    34     }
    35 }
    36 int main(void)
    37 {
    38     cin>>n>>m;
    39     for(int i=1;i<=m;++i)
    40     {
    41         cin>>a[i][0]>>a[i][1];
    42     }
    43     cin>>k;
    44     for(int i=1;i<=k;++i)
    45     {
    46         cin>>c[i][0]>>c[i][1];
    47     }
    48     dfs(1);
    49     cout<<ans<<endl;
    50     return 0;
    51 }

    D:

    给定一个整数N,求有多少个公差为1的等差数列,使得数列和为N。

    分析:我们只需考虑数列为正整数的情况,然后乘2即可。因为对于任意一个满足条件的正整数数列a1,a2,……,an,都可以在前面添加一个首项为-a1+1,末项为a1-1的等差数列,使得和仍为N。假设项数为i,那么有(1+i)*i<=2*N。我们枚举每个项数,判断是否合法。

    (1)若i为奇数,仅需判断N是否整除i。

    (2)若i为偶数:如果N为奇数,那么i不能为4的倍数;如果N为偶数,那么i应为4的倍数。同时对任意N,还要满足N整除i/2,而且N/(i/2)为奇数。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <vector>
     7 #include <map>
     8 #include <cstdlib>
     9 #include <cstring>
    10 #include <cmath>
    11 #include <set>
    12 #include <unordered_set>
    13 typedef long long ll;
    14 const int INF=0x3f3f3f3f;
    15 using namespace std;
    16 ll n,ans;
    17 int main(void)
    18 {
    19     cin>>n;
    20     for(ll i=1;i*i+i<=2*n;++i)
    21     {
    22         if(i&1)
    23         {
    24             if(n%i==0)ans+=2;
    25         }
    26         else
    27         {
    28             if(n%2==1&&i%4!=0&&n%(i/2)==0&&(n/(i/2))%2==1||n%2==0&&i%4==0&&n%(i/2)==0&&(n/(i/2))%2==1)ans+=2;
    29         }
    30     }
    31     cout<<ans<<endl;
    32     return 0;
    33 }

    E:

    有N种宝石和M对组合,表示第Ai和Bi种宝石可以相邻。其他的不能相邻。给出K种需要的宝石,分别为C1,C2,……,Ck,是否存在一个序列满足K种宝石都出现一次及以上,若有输出需要的最小宝石数量。

    分析:设dis[i][j]表示i和Cj的最小距离(可以通过对每种需要的宝石进行一次BFS求出),dp[i][state]表示以Ci结尾的状态为state时所需要的最少宝石数(例如state为101,表示序列中有C1和C3)。那么dp[i][state]=min(dp[j][state']+dis[Cj][i]),最终答案为min(dp[i][(1<<K)-1],0<=i<K)。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <vector>
     7 #include <map>
     8 #include <cstdlib>
     9 #include <cstring>
    10 #include <cmath>
    11 #include <set>
    12 typedef long long ll;
    13 const int INF=0x3f3f3f3f;
    14 using namespace std;
    15 int n,m,k,dis[110000][18],arr[18];
    16 int dp[18][(1<<18)];
    17 vector<int>e[110000];
    18 void bfs(int t)
    19 {
    20     for(int i=1;i<=n;++i)dis[i][t]=INF;
    21     queue<int>que;
    22     que.push(arr[t]);
    23     dis[arr[t]][t]=0;
    24     while(!que.empty())
    25     {
    26         int p=que.front();
    27         que.pop();
    28         for(int i=0;i<e[p].size();++i)
    29         {
    30             int v=e[p][i];
    31             if(dis[v][t]==INF)
    32             {
    33                 dis[v][t]=dis[p][t]+1;
    34                 que.push(v);
    35             }
    36         }
    37     }
    38 }
    39 int solve(int last,int t)
    40 {
    41     if(t==((1<<k)-1))return 0;
    42     int &ret=dp[last][t];
    43     if(ret!=-1)return ret;
    44     ret=INF;
    45     for(int i=0;i<k;++i)
    46     {
    47         if(t&(1<<i))continue;
    48         ret=min(ret,solve(i,t|(1<<i))+dis[arr[last]][i]);
    49     }
    50     return ret;
    51 }
    52 int main(void)
    53 {
    54     memset(dp,-1,sizeof(dp));
    55     cin>>n>>m;
    56     for(int i=0;i<m;++i)
    57     {
    58         int u,v;
    59         cin>>u>>v;
    60         e[u].push_back(v);
    61         e[v].push_back(u);
    62     }
    63     cin>>k;
    64     for(int i=0;i<k;++i)cin>>arr[i];
    65     for(int i=0;i<k;++i)bfs(i);
    66     for(int i=0;i<k;++i)
    67     {
    68         if(dis[arr[0]][i]==INF)
    69         {
    70             cout<<"-1"<<endl;
    71             return 0;
    72         }
    73     }
    74     int ans=INF;
    75     for(int i=0;i<k;++i)
    76     {
    77         ans=min(ans,1+solve(i,(1<<i)));
    78     }
    79     cout<<ans<<endl;
    80     return 0;
    81 }

    F:

    给出0到N-1的一组排列,将排列向左移位k次,k=0,1,……,N-1,求每次移位后的排列的逆序对数。

    分析:我们先算出刚开始的排列的逆序对数x0。每次移位相当于把第一个数放到末尾。对于第i次移位,假设第i-1次移位后的逆序对数为x,第一个数为a0,那么我们只需减去在第i-1次移位中a0的贡献P1,再加上在第i次移位中a0的贡献P2即可。由于这是0到N-1的排列,可以知道P1=a0(所有比他小的数),P2=N-1-a0(所有比他大的数),因此通过循环更新x0即可。

    关于求逆序对,可以看一下这道题:https://www.luogu.com.cn/problem/P1908

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <vector>
     7 #include <map>
     8 #include <cstdlib>
     9 #include <cstring>
    10 #include <cmath>
    11 #include <set>
    12 typedef long long ll;
    13 const int INF=0x3f3f3f3f;
    14 using namespace std;
    15 int a[310000],b[310000],c[310000],n;
    16 ll ans;
    17 void msort(int h,int r)
    18 {
    19     if(h==r)return;
    20     int mid=(h+r)/2,i=h,j=mid+1,k=h;
    21     msort(h,mid);
    22     msort(mid+1,r);
    23     while(i<=mid&&j<=r)
    24     {
    25         if(a[i]<=a[j])
    26         {
    27             c[k++]=a[i++];
    28         }
    29         else
    30         {
    31             c[k++]=a[j++];
    32             ans+=mid-i+1;
    33         }
    34     }
    35     while(i<=mid)c[k++]=a[i++];
    36     while(j<=r)c[k++]=a[j++];
    37     for(int i=h;i<=r;++i)a[i]=c[i];
    38 }
    39 int main(void)
    40 {
    41     scanf("%d",&n);
    42     for(int i=1;i<=n;++i)
    43     {
    44         scanf("%d",&a[i]);
    45         b[i]=a[i];
    46     }
    47     msort(1,n);
    48     cout<<ans<<endl;
    49     for(int i=1;i<n;++i)
    50     {
    51         ans-=b[i];
    52         ans+=n-1-b[i];
    53         cout<<ans<<endl;
    54     }
    55     return 0;
    56 }
    终究独木难支。
  • 相关阅读:
    HDU 1505 City Game
    HDU 1506 Largest Rectangle in a Histogram
    HDU 1838 Chessboard
    HDU 2512 一卡通大冒险
    HDU 1081 To The Max
    HDU 2845 Beans
    HDU 1422 重温世界杯
    HDU 1231 最大连续子序列
    第6章 接口和实现
    java面向抽象编程样例
  • 原文地址:https://www.cnblogs.com/yanying7/p/14351366.html
Copyright © 2020-2023  润新知