ArabellaCPC 2019

链接:http://codeforces.com/gym/102263

A:

签到题:A * B 。


 B:

题意:类似取石子游戏,每个人可以取max(1, n(当前剩余) - k)个,最后取完的人赢,Kilani先取,问谁能获胜。

思路:一眼就看出是博弈论,找了几种情况推了下发现只有 (n - k <= 1 && n不是偶数 )的情况下 后手才能赢。

AC代码:

 

 1 #include
 2 using namespace std;
 3 int main()
 4 {
 5     std::ios::sync_with_stdio(false);
 6     int t;
 7     cin >> t;
 8     while(t--)
 9     {
10         int n, k;
11         cin >> n >> k;
12         if(n - k <= 1 && n % 2 == 0) cout <<"Ayoub" <<endl;
13         else cout << "Kilani" <<endl;
14     }
15     return 0;
16 }

 C:

题意:给你26个字母键、大小写切换键、空格键和删除键,问在一系列操作后打出的字符串和给定的字符串相不相等。

思路:模拟一遍,不过删除不能删到负的orz。

AC代码:

 1 #include 
 2 using namespace std;
 3 const int maxn = 1e7 + 10;
 4 int n, L, k;
 5 char s[maxn], a[maxn], b[maxn], c[maxn];
 6 int main()
 7 {
 8     std::ios::sync_with_stdio(false);
 9     cin >> n;
10     for(int i = 1; i <= n; i++)
11     {
12         cin >> s;
13         for (int j = 0; j < strlen(s); j++)
14             a[++L] = s[j];
15         a[++L] = ' ';
16     }
17     L--;
18     cin >> k;
19     int pos = 0, t = 0;
20     for (int i = 1; i <= k; i++)
21     {
22         cin >> c;
23         if (c[0] == 'C')
24             t = (t + 1) % 2;
25         else if (c[0] == 'B')
26         {
27             if (pos > 0)
28                 pos--;
29         }
30         else if (c[0] == 'S')
31             b[++pos] = ' ';
32         else if (t == 0)
33             b[++pos] = c[0];
34         else
35             b[++pos] = c[0] - 32;
36     }
37     bool flag = true;
38     if (pos != L)
39         flag = false;
40     for (int i = 1; i <= L; i++)
41         if (b[i] != a[i])
42             flag = false;
43     if(flag) cout << "Correct" << endl;
44     else cout << "Incorrect" <<endl;
45 }

 D:

题意:给你俩个数组,数组一中的任意元素可以加上或者减去数组二中的任意元素, 问不限操作次数能否使数组一种所有元素相等。

思路:求出第二数组的最小公倍数,然后差值在其之内和其倍数的都是yes。虽然不是很懂为什么,但是枚举了几个例子发现的确是这样。

AC代码:

 1 #include
 2 using namespace std;
 3 const int maxn = 1e6 + 5;
 4 typedef long long ll;
 5 ll a[maxn], b[maxn];
 6 int main()
 7 {
 8     std::ios::sync_with_stdio(false);
 9     int n, m;
10     cin >> n >> m;
11     for(int i = 0;i < n;i++) cin >> a[i];
12     for(int i = 0;i < m;i++) cin >> b[i];
13     ll d;
14     if(m == 1) d = b[0];
15     else
16     {
17         d = __gcd(b[0],b[1]);
18         for(int i = 2;i )
19         {
20             d = __gcd(d, b[i]);
21         }
22 
23     }
24     bool flag = true;
25     for(int i = 1;i < n;i++)
26     {
27         if(abs(a[i] - a[0]) % d) {flag = false;break;}
28     }
29     if(flag) cout << "Yes" <<endl;
30     else cout << "No" <<endl;
31     return 0;
32 }

 


E:


F:


G:

题意:求所有可能结果的期望值。

思路:算了很久还是一团浆糊,感觉还是无从入手。看了题解才知道,只要考虑 i 对结果的贡献是多少, 对于每个 i ,只有每个比他 小的数才能对结果产生贡献,所有一共有 i - 1种,所以概率为(i - 1)/ n.

AC代码:

 1 #include
 2 using namespace std;
 3 typedef long long ll;
 4 int main()
 5 {
 6     double n;
 7     double ans = 0;
 8     scanf("%lf",&n);
 9     for(int i = 2;i <= n;i++)
10     {
11         ans += (i - 1)/n * i;
12     }
13     printf("%.12f\n",ans);
14     return 0;
15 }

 


H:

 题意: n个饼,k个锅,一个锅可以煎俩个饼,一个饼有俩面,一个面要煎 5 min,问煎完所有饼的最小时间。

思路:从样例中可以看出 即使饼没有一起煎但最优解还是能做到平均每个饼耗时5分钟。嗯...怎么讲呢 ,反正不超过可用锅的一半就可以换着煎...。

AC代码

 1 #include 
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e7+10;
 5 const int inf=0x3f3f3f3f;
 6 ll n,k;
 7 int main(){
 8     cin >> n >> k;
 9     if(2LL * k >= n){
10         cout << 10 << endl;
11     }
12     else{
13             if(n % k != 0)
14                 cout << (n/k+1) *5LL <<endl;
15             else cout << n/k *5LL << endl;
16  
17     }
18     return 0;
19 }

 I:

 题意:给你一个大小为n的数组,分别求出 (2 ~ n)大小个子序列中F(S)的最大值。

思路:排序 每次取数组俩端,因为对于每个数求差的值其实就是子序列最大值减 最小值。

AC代码:

#include
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 5;
ll a[maxn];
ll ans[maxn];
int main()
{
    std::ios::sync_with_stdio(false);
    int n;
    cin >> n;
    for(int i = 0;i < n;i ++)
    {
        cin >> a[i];
    }
    sort(a, a + n);
    int  l = 0,r = n - 1;
    int k = 2;
    long long ans = 0;
    long long sum = 0;
    while(k <= n)
    {
        if(k % 2 == 0)
            sum += a[r--] - a[l++];
        ans += sum;
        cout << ans << " ";
        k++;
    }
    return 0;
}

 J:

题意:给你一个数 a,b一开始值为0,你可以给b加上或者减去 10的x(x > 0) 次方,问最少要几次b能等于a。

思路:一个是每位直接从0加,一个是从10往下走 例如 99可以先 100 再减1.对于每位数在俩者中取最优的比较即可。想是想到了,结果自己写的太丑,就WA了。

AC代码:

#include
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int a[maxn];
int main()
{
    string s;
    cin >> s;
    for(int i = 0;i < s.size();i++)
    {
       a[i] = s[i] - '0';
    }
    int ans = a[0], sum = 10 - a[0] + 1;
    for(int i = 1; i < s.size();i++)
    {
        int t = ans, k = sum;
        ans = min(t + a[i], k + a[i]);
        sum = min(10 - a[i] + 1 + t, 10 - a[i] + k - 1);
    }
    cout << min(ans, sum);
    return 0;
}

 


K:


L:


M:

签到题:桶排,进位,输出,没了。

AC代码:

 1 #include
 2 using namespace std;
 3 int vis[27];
 4 int main()
 5 {
 6     std::ios::sync_with_stdio(false);
 7     string s;
 8     cin >> s;
 9     for(int i = 0;i < s.size();i++)
10     {
11         int t = s[i]- 'a';
12         vis[t] ++;
13     }
14     for(int i = 0;i < 25;i++)
15     {
16         vis[i + 1] += vis[i]/2;
17         vis[i] %= 2;
18     }
19     for(int i = 25;i >= 0;i--)
20     {
21         char t = i + 'a';
22         for(int j = 0;j < vis[i];j++)
23         {
24             cout << t;
25         }
26     }
27     cout << endl;
28     return 0;
29 }

 

转载于:https://www.cnblogs.com/Carered/p/11342022.html

你可能感兴趣的:(ArabellaCPC 2019)