SMU ACM 2021划水赛

比赛链接

A P6284 [COCI2016-2017#1] Tarifa

水题

#include<bits/stdc++.h>
using namespace std;

const int N = 1005;
int n , a[N] , b[N] , cnt1 , cnt2;
set<int> c;

inline int read()
{
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

int main()
{
    int x = read() , n = read() , sum = 0;
    for( int i = 1 , y ; i <= n ; i ++ )
        y = read() , sum += y;
    cout << x * (n+1) - sum  << endl;
    return 0;
}

B P6320 [COCI2006-2007#4] SIBICE

最长边是对角线,小技巧不用开方

#include<bits/stdc++.h>
using namespace std;

const int N = 1005;
int n , a[N] , b[N] , cnt1 , cnt2;
set<int> c;

inline int read()
{
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

int main()
{
    int n = read() , w = read() , h = read() , l = w * w + h * h ;
    for( int i = 1 , x ; i <= n ; i ++ )
    {
        x = read();
        if( x * x <= l ) printf("DA\n");
        else printf("NE\n");
    }
    return 0;
}

C P6321 [COCI2006-2007#4] SKENER

这个问题分开了考虑,如果每一行重复\(r\)

for( int i = 1 ; i <= ; i ++ )
    for( int k = 1 ; k <= r ; k ++ )
    {
        for( int j = 1 ; j <= m ; j ++ )
            cout << g[i][j];
        cout << endl;
    }

如果每一列重复\(c\)

for( int i = 1 ; i <= ; i ++ )
{
    for( int j = 1 ; j <= ; j ++ )
        for( int k = 1 ; k <= c ; k ++ )
            cout << g[i][j];
    cout << endl;
}

把两种情况和起来就好了

#include<bits/stdc++.h>
using namespace std;

int n , m , r , c;
string s;

int main()
{
    cin >> n >> m >> r >> c;
    for( int i = 1 ; i <= n ; i ++ )
    {
        cin >> s;
        for( int k = 1 ; k <= r ; k ++ ) {
            for (auto it: s)
                for (int j = 1; j <= c; j++)
                    cout << it;
            cout << endl;
        }

    }
    return 0;
}

D P1413 坚果保龄球

这道题可以把所有的僵尸认为是静止不动的,然后每个僵尸的坐标就是\((p,t)\),然后问最少需要多少个\(1\times60\)的矩形可以覆盖所有的僵尸

每一行都是相互独立的,对于每一行贪心的覆盖就好了

#include<bits/stdc++.h>
#define l first
#define r second
using namespace std;

int n , cnt ;
vector<int> s[8];

inline int read()
{
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

int main()
{
    n = read();
    for( int p , t ; n ; n -- )
    {
        p = read() , t = read();
        s[p].push_back(t);
    }
    for( int i = 1 , t = -1 ; i <= 6 ; t = -1 , i ++ )
    {
        sort( s[i].begin() , s[i].end() );

        for( int j = 0 ; j < s[i].size() ; j ++ )
        {
            if( t == -1 ) t = s[i][j];
            else if( t + 60 - 1 >= s[i][j] ) continue;
            else cnt ++ , t = s[i][j];
        }
        cnt += (t > 0 );
    }
    cout << cnt << endl;
    return 0;
}

P1901 发射站

最近的且比他高,要先满足比他高,正常的逻辑应该是暴力找就好但是会TLE

向左发射能量和向右类似,我们先处理向右的

首先从左侧开始枚举,用一个队列维护之前的递减序列,这个序列均没有向右发射过能量,对于当前的能量站只要比队列头高,就是离队头最近切比他高的,就会收到对头的能量,然后就要弹出对头,重复这个过程直到比队头低或者队空,然后当前的能量站入队

对于向左发射过程基本相同倒着做一遍就好,最后在扫描一遍就好了,因为每一个只会入队两次出队两次所以

#include<bits/stdc++.h>
#define l first
#define r second
using namespace std;

const int N = 1e6+5;
int n , h[N] , v[N] , val[N] , res = 0;
stack<int> s;

inline int read()
{
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

int main()
{
    n = read();
    for( int i = 1 ; i <= n ; i ++ )
        h[i] = read() , v[i] = read();
    for( int i = 1 ; i <= n ; i ++ )
    {
        if( s.empty() ){
            s.push( i );
            continue;
        }
        while( s.size() && h[s.top()] < h[i] )
            val[i] += v[s.top()] , s.pop();
        s.push(i);
    }
    while( s.size() ) s.pop();
    for( int i = n ; i >= 1 ; i -- )
    {
        if( s.empty() ){
            s.push( i );
            continue;
        }
        while( s.size() && h[s.top()] < h[i] )
            val[i] += v[s.top()] , s.pop();
        s.push(i);
    }
    for( int i = 1 ; i <= n ; i ++ )
        res = max( res , val[i] );
    cout << res << endl;
    return 0;
}
posted @ 2022-03-15 14:53  PHarr  阅读(46)  评论(0编辑  收藏  举报