AtCoder Beginner Contest 190

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:

待补。

 

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 }

 

上一篇:AtCoder Beginner Contest 190 题解


下一篇:188数码管驱动程序(简洁)