题目主要选自 Gym 100985A - Gym 100985M

简直就是阅读理解专场。。。

题意比题目还难。。。

一共13道题,勉强做出来12道,题目不难,题意难。

看来需要好好学学英语了。

 

A题:

题意介绍的很花哨,其实就是判断两个数的最大公因数是否为1。

刚开没能清楚的理解题意,其中题目中有一句是因数尽可能的少

  • Each of these ids were chosen in a way such that they would have the least amount of divisors possible.

因为这一句我还以为是分解两个数的质因子,唉。。

// #include <bits/stdc++.h>

// using namespace std;
// typedef long long LL;

// map<LL, LL> mp1, mp2;
// vector<LL> v1, v2;

// map<LL,LL>  divd(LL x)
// {
//     map<LL, LL> mp;
//     LL cnt = 2;
//     while(1)
//     {
//         while(x % cnt == 0)
//         {
//             x /= cnt;
//             mp[cnt] ++;
//         }
//         cnt++;
//         if(x == 1)
//             break;
//     }
//     return mp;
// }

// int main()
// {
//     int t;
//     scanf("%d", &t);
//     while(t--)
//     {
//         mp1.clear();
//         mp2.clear();
//         v1.clear();
//         v2.clear();
//         LL num1, num2;
//         scanf("%lld %lld", &num1, &num2);
//         mp1 = divd(num1);
//         mp2 = divd(num2);

//         int len1 = mp1.size();
//         int len2 = mp2.size();
//         map<LL, LL>::iterator it;
//         for(it = mp1.begin(); it != mp1.end(); it++)
//         {
//             v1.push_back(it->first);
//         }
//         for(it = mp2.begin(); it != mp2.end(); it++)
//         {
//             v2.push_back(it->first);
//         }

//         int len = min(v1.size(), v2.size());
//         bool flag = false;
//         for(int i=0; i<len; i++)
//         {
//             if(v1[i] == v2[i])
//             {
//                 flag = true;
//                 break;
//             }
//         }

//         if(flag)
//             printf("Sim\n");
//         else 
//             printf("Nao\n");

//     }


//     return 0;
// }



#include <bits/stdc++.h>

using namespace std;
typedef long long LL;

LL gcd(LL a, LL b)
{
    return !b ? a : gcd(b, a%b);
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        LL num1, num2;
        scanf("%lld %lld", &num1, &num2);
        if(gcd(num1, num2) != 1)
            printf("Sim\n");
        else
            printf("Nao\n");

    }



    return 0;
}

 

B题:

n个杯子,每个杯子上面有一个数,每次只能抽其中一个杯子,如果抽的杯子上面的数,不是游戏最后的答案还要继续抽,问一个人在最糟糕的情况下用最好的策略最少要抽几次?

题目描述的是这个意思,一直没想明白最好的策略是什么策略,我就假设结果是最后一个数,模拟二分的情况,二分了几次,就是抽多少次,结果就对了。。。。

#include <bits/stdc++.h>

using namespace std;
const int N = 100010;

int a[N];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        scanf("%d", &a[i]);
    }
    int cnt = 0;
    while(n)
    {
        n = n / 2;
        cnt ++;
    }
    printf("%d\n", cnt);


    return 0;
}

C题:

nim博弈,第一次取较多的堆,使两堆相等,下一次取完其中一堆。f

flush(stdout); 是题目要求加上去的。

#include <bits/stdc++.h>


using namespace std;


int main()
{
    int x, y;
    while(scanf("%d %d", &x, &y) != EOF)
    {
        if(x > y)
            printf("%d %d\n", 1, x-y);
        else if(x < y)
            printf("%d %d\n", 2, y-x);
        else if(x == y)
        {
            printf("%d %d\n", 2, y);
        }
        fflush(stdout);
    }

    

    return 0;
}

D题:

不会。。

E题:

用前缀和数组。

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 100010;

int a[N];
LL sum[N];

int main()
{
    int n, m;
    while(scanf("%d %d", &n, &m) != EOF)
    {
        memset(sum, 0, sizeof(sum));
        sum[0] = 0;
        for(int i=1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            sum[i] = sum[i-1] + a[i];
        }
        int l, r;
        for(int i=0; i<m; i++)
        {
            scanf("%d %d", &l, &r);
            LL ans = sum[r] - sum[l-1];
            if(ans % 2 == 0)
                printf("Sim\n");
            else 
                printf("Nao\n");
        }
    }



    return 0;
}

F题:

题意难懂,其中还要向上取整,ceil()函数

#include <bits/stdc++.h>

using namespace std;


int main()
{
    int n, m, k;
    scanf("%d %d %d", &n, &m, &k);

    // int percent;
    // if(0.7 * n > (int) 0.7 * n)
    //     percent = 0.7 * n + 1;
    // else
    //     percent = 0.7 * n;
    int percent = ceil(0.7 * n);
    

    int ans1 = 0, ans2 = 0;
    if(percent > k)
        ans1 = percent - k;
    else  
        ans1 = 0;
    ans2 = 100 * (k + n - m) / n;
    if(ans2 < 70)
        ans1 = -1;
    
    printf("%d\n", ans1);
    printf("%d\n", ans2);


    return 0;
}

G题:

用栈,A入站,遇到B就将A出栈,栈里没有A就不能配对,如果最后栈不为空,也不能配对

#include <bits/stdc++.h>

using namespace std;
const int N = 100010;

char str[N];
stack<int> s;


int main()
{
    while(!s.empty())   s.pop();
    scanf("%s", str);
    int len = strlen(str);
    bool flag = false;
    for(int i=0; i<len; i++)
    {
        if(str[i] == 'A')
            s.push(1);
        else if(str[i] == 'B')
        {
            if(!s.empty())
                s.pop();
            else
            {
                flag = true;
                break;
            }
        }
    }
    if(flag || !s.empty())
        printf("Nao\n");
    else 
        printf("Sim\n");


    return 0;
}

H题:

求n维空间两点直接的距离,套用公式。

#include <bits/stdc++.h>

using namespace std;
const int N = 100010;
typedef long long LL;

int a[N], b[N], c[N];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i=0; i<n; i++)
        scanf("%d", &a[i]);
    for(int j=0; j<n; j++)
        scanf("%d", &b[j]);
    for(int k=0; k<n; k++)
        scanf("%d", &c[k]);
    
    LL ab = 0;
    for(int i=0; i<n; i++)
    {
        ab = ab + 1LL * (a[i] - b[i]) * (a[i] - b[i]);
    }
    LL ac = 0;
    for(int i=0; i<n; i++)
    {
        ac = ac + 1LL * (a[i] - c[i]) * (a[i] - c[i]);
    }
    if(ab <= ac)
        printf("Yan\n");
    else 
        printf("MaratonIME\n");


    return 0;
}

I题:

正着和倒着比较, 一定要吃完才算

#include <bits/stdc++.h>

using namespace std;
const int N = 100010;

int a[N];

int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i=0; i<n; i++)
    {
        scanf("%d", &a[i]);
    }

    int cnta = 0, cntb= 0;
    int suma = m, sumb = m;
    for(int i=0; i<n; i++)
    {
        if(suma >= a[i])
        {
            cnta ++;
            suma -= a[i];
        }
        else
            break;
    }
    for(int i=n-1; i >= 0; i--)
    {
        if(sumb >= a[i])
        {
            cntb ++;
            sumb -= a[i];
        }
        else
            break;
    }

    // printf("%d %d\n", cnta, cntb);
    if(cnta > cntb)
        printf("Yan\n");
    else if(cnta < cntb)
        printf("Nathan\n");
    else
    {
        printf("Empate\n");
    }
    



    return 0;
}

J题:

判断几个圆相切或相交,如果有,就把这样的成对输出。

#include <bits/stdc++.h>

using namespace std;
const int N = 10010;
typedef long long LL;
typedef pair<int, int> P;

struct node{
    int x, y, r;
};
struct node cle[N];
vector<P> v;

int main()
{
    int n;
    scanf("%d", &n);
    for(int i=1; i <= n; i++)
    {
        scanf("%d %d %d", &cle[i].x, &cle[i].y, &cle[i].r);
    }
    v.clear();
    for(int i=1; i<=n; i++)
    {
        for(int j=i+1; j<=n; j++)
        {
            double dis = sqrt(pow(1.0 * cle[i].x - cle[j].x, 2) + pow(1.0 * cle[i].y - cle[j].y, 2));
            if(dis <= cle[i].r + cle[j].r)
                v.push_back(P(i, j));
        }
    }
    // printf("%d %d", v[0].first, v[0].second);
    int len = v.size();
    for(int i=0; i<len; i++)
    {
        printf("%d %d ", v[i].first, v[i].second);
    }
    printf("\n");


    return 0;
}

K题:

字符串简写

#include <bits/stdc++.h>


using namespace std;
const int N = 100010;

char s[N];
// int a[N];

int main()
{
    scanf("%s", s);
    int len = strlen(s);
    for(int i=0; i<len; i++)
    {
        int j = i;
        int cnt = 0;
        for(j=i; j<len; j++)
        {
            if(s[j] == s[i])
                cnt ++;
            else
                break;
        }
        printf("%c%d", s[i], cnt);
        i = j-1;
    }



    return 0;
}

L题:

找出最大数,一定要是最大,不能有并列

#include <cstdio>
#include <algorithm>

using namespace std;
const int N = 100010;

int a[N];

int main()
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        int maxnum = -1;
        int index = -1;
        for(int i=0; i<n; i++)
        {
            scanf("%d", &a[i]);
            if(maxnum < a[i])
            {
                maxnum = a[i];
                index = i;
            }
        }
        int cnt = 0;
        for(int i=0; i<n; i++)
        {
            if(maxnum == a[i])
            {
                cnt ++;
            }
        }

        if(cnt > 1)
            printf("-1");
        else
            printf("%d\n", index + 1);

       
    }


    return 0;
}

M题:

按指定格式,把一个矩阵给遍历一遍,vector要预处理一个0,不然会RE

#include <bits/stdc++.h>

using namespace std;
const int N = 10010;

char mp[N][N];
vector<int> v;

int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i=0; i<n; i++)
    {
        scanf("%s", mp[i]);
    }
    v.clear();
    v.push_back(0);
    int money = 0;
    for(int i=0; i<n; i++)
    {
        int j;
        if(i % 2 == 0)  j = 0;
        else    j = m-1;
        
        if(j == 0)
        {
            for(j = 0; j<m; j++)
            {
                if(mp[i][j] == '.')
                    money ++;
                else if(mp[i][j] == 'L')
                {
                    v.push_back(money);
                    money = 0;
                }
            }
        }
        else if(j == m-1)
        {
            for( ; j >= 0; j--)
            {
                if(mp[i][j] == '.')
                    money ++;
                else if(mp[i][j] == 'L')
                {
                    v.push_back(money);
                    money = 0;
                }
            }
        }

    }

    sort(v.begin(), v.end());
    printf("%d\n", v[v.size() - 1]);


    return 0;
}