Codeforces Good Bye 2016部分题解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27008079/article/details/53979953

Codeforces Good Bye 2016部分题解

今年的最后一场cf,打的并不好,感觉自己元旦期间好松懈。
题目链接

A. New Year and Hurry

这里写图片描述
这里写图片描述
题意:
现在20:00,Limak需要在24:00点前赶去派对,此时有n个问题,第i个问题花费时间5*i 分钟,从家到派队需要k分钟,问最多解决几个问题

思路:
纯模拟。

#include<iostream>
using namespace std;
int main()
{
    int n, k;
    int i = 0, j;
    cin >> n >> k;
    int s = k;
    if(s <= 240)
    for(i=1; i<=n; i++)
    {

        s += i * 5;
        if(s > 240){
            break;
        }
    }

    cout << i - 1 << endl;
    return 0;
 } 

B. New Year and North Pole

这里写图片描述
这里写图片描述
题意:
假定地球是标准的球体,从北极点到南极点长度40000km,赤道长度40000km,Limak目前在北极点,有以下规则:1.当Limak处于或行走过程中处于南极点时,他只能向北走。2.当Limak处于或行走过程中处于北极点时,他只能向南走。3.Limak最后要回到北极点。给出n个行走步骤,问是否合法。

思路:
思维题,行走中向东和向西走不用管,只用管南北方向的行走,判断处于两个极点时是否下一步是按规定走的,最后判断是否回到北。

#include<string>
#include<iostream>
using namespace std;
int main()
{
    int n;
    int i, j, k;
    int x;
    string str;

    cin >> n;
    int sum = 0;
    bool pd = true;
    for(i=1; i<=n; i++)
    {
        cin >> x >> str;
        if(sum == 0 && str != "South"){
            pd = false;
        } 
        else if(sum == 20000 && str != "North"){
            pd = false;
        }
        else if(str == "South")
        {
            if(sum >= 0 && sum < 20000){
                if(x + sum > 20000){
                    pd = false;
                }
                else{
                    sum += x;
                }
            }
            else{
                if(sum - x < 20000){
                    pd = false;
                }
                else{
                    sum -= x;
                }
            }
        }
        else if(str == "North")
        {
            if(sum > 0 && sum <= 20000){
                if(sum - x < 0){
                    pd = false;
                }
                else{
                    sum -= x;
                }
            }
            else{
                if(x + sum > 40000){
                    pd = false;
                }
                else{
                    sum += x;
                    if(sum == 40000){
                        sum = 0;
                    }
                }
            }
        }

    }
    if(!pd || sum != 0){
        cout << "NO\n";
    }
    else{
        cout << "YES\n";
    }
}

C. New Year and Rating

这里写图片描述
这里写图片描述
题意:
每场比赛有积分,处于>=1900参加div1,<1900参加div2,Limak今年参加了n场比赛,现给出每场比赛的轮次和比赛后的积分变化,问最后能获得的最大积分为多少。

思路:
从后往前,假设最后得分为x,根据第一组数据可列不等式
x - 8 <= 1899
x - 8 - 5 <= 1899
x - 8 - 5 + 7 >= 1900

#include<iostream>
using namespace std;
int array[200001][2];
const int INF = 1000000000;
const int FINF = -1000000000;
int main()
{
    int i, j, k;
    int n;
    cin >> n;
    for(i=1; i<=n; i++)
    {
        cin >> array[i][0] >> array[i][1];
    }

    int sum = 0;
    int maxx = INF;
    int minn = FINF;
    for(i=n; i>=1; i--)
    {
        sum -= array[i][0];
        if(array[i][1] == 2)
        {
            int t = 1899 - sum;
            if(t < maxx){
                maxx = t;
            }
        }
        else{
            int t = 1900 - sum;
            if(t > minn){
                minn = t;
            }
        }
    }

    if(maxx == INF){
        cout << "Infinity\n";
    }
    else if(maxx < minn)
    {
        cout << "Impossible\n"; 
    }
    else{
        cout << maxx << endl;
    }
    return 0;
 } 

D. New Year and Fireworks

这里写图片描述
这里写图片描述
题意:
放烟花,经下图n次迭代后最多多少个
这里写图片描述

思路:
记忆化搜索,首先注意到t<=5,且迭代次数<=30,因此数组最大300 * 300,定义状态dp[x][y][t][d],表示处于x行y列,迭代第t次,方向为d

int dict[8][2] = {{-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}};
//.......
dfs(x, y, t + 1, (d + 7) % 8);
dfs(x, y, t + 1, (d + 1) % 8);

每次递归方向为d-1和d+1

 #include<iostream>
 using namespace std;

int dict[8][2] = {{-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}};
int dp[310][310][31][9];
int array[310][310];
int value[31];
int n;

void dfs(int x, int y, int t, int d)
{
    if(dp[x][y][t][d]){
        return ;
    }
    if(t > n){
        return;
    } 

    int i;
    dp[x][y][t][d] = 1;
    for(i=0; i<value[t]; i++)
    {
        x += dict[d][0];
        y += dict[d][1];
        array[x][y] = 1;
    }

    dfs(x, y, t + 1, (d + 7) % 8);
    dfs(x, y, t + 1, (d + 1) % 8);
}

int main()
{
    int i, j, k;

    cin >> n;
    for(i=0; i<n; i++)
    {
        cin >> value[i];
    }

    dfs(151, 151, 0, 0);
    int ans = 0;
    for(i=1; i<310; i++)
    for(j=1; j<310; j++)
    {
        if(array[i][j])
        {
            ans++;
        }
    }
    cout << ans << endl;

}

猜你喜欢

转载自blog.csdn.net/qq_27008079/article/details/53979953