1. 程式人生 > 其它 >SMU2017年校賽 題解

SMU2017年校賽 題解

比賽連結

A.星圖

l[i],r[i],u[i],d[i]分別代表第\(i\)行或(列)從某個方向看過去的第一個黑洞所在位置

然後判斷對應的黑洞是否在當前點的後面

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


const int N = 1005;
int n , m , q , l[N] , r[N] , d[N] , u[N] ;
char mp[N][N];

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

int main()
{
    n = read() , m = read() , q = read();
    memset( u , 0x3f3f3f3f , sizeof(u) ) , memset( l , 0x3f3f3f3f , sizeof( l ) );
    for( int i = 1 , f ; i <= n ; i ++ )
    {
        f = 1 ;
        scanf( "%s" , mp[i] + 1 );
        for( int j = 1 ; j <= m ; j ++ )
        {
            if( mp[i][j] == '#' )
            {
                if(f) f = 0 , l[i] = j;
                r[i] = j;
                d[j] = i;
            }
        }
    }

    for( int j = 1 ; j <= m ; j ++ )
    {
        for( int i = 1 ; i <= n ; i ++ )
        {
            if( mp[i][j] == '#' )
            {
                u[j] = i;
                break;
            }
        }
    }

    int x , y ;
    char dir;
    for( int i = 1 ; i <= q ; i ++ )
    {
        x = read() , y = read() , scanf( "%c" , &dir );
        if( dir == 'L' ) puts( l[x] > y ? "YES" : "NO" );
        else if( dir == 'R' ) puts( r[x] < y ? "YES" : "NO" );
        else if( dir == 'D' ) puts( d[y] < x ? "YES" : "NO" );
        else puts( u[y] > x ? "YES" : "NO" );
    }
    return 0;
}

B.好數

若存在大於等於兩個數,則必有一數與第一個數不相同

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

int main()
{
    string s;
    cin >> s;
    for( auto it : s )
    {
        if( it != s[0] )
        {
            cout << "NO";
            exit(0);
        }
    }
    cout << "YES\n";
}

C.裝進肚子

貪心,早上甜蜜值減去晚上甜蜜值,越大越適合早上吃

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

const int N = 100005;
int n , k ;
long long ans;
struct Node
{
    int x , y;
    friend bool operator < ( Node a , Node b ) { return a.x - a.y > b.x - b.y; }
} a[N];

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

int main()
{
    n = read() , k = read();
    for( int i = 1 ; i <= n ; i ++ ) a[i].x = read();
    for( int i = 1 ; i <= n ; i ++ ) a[i].y = read();
    sort( a + 1 , a + 1 + n );
    for( int i = 1 ; i <= k ; i ++ ) ans += a[i].x;
    for( int i = k + 1 ; i <= n ; i ++ ) ans += a[i].y;
    cout << ans << endl;
}

D.ZZZZone愛吃糖

字首和

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

long long n , a[10005] , m , ans;

int main()
{
    cin >> n;
    for( int i = 1 ; i <= n ; i ++ ) cin >> a[i] , a[i] += a[ i - 1 ];
    cin >> m;
    for( int i = 1 , l , r ; i <= m ; i ++ )
    {
        cin >> l >> r;
        ans += max( 0LL , a[r] - a[ l - 1 ] );
    }
    cout << ans << endl;
    return 0;
}

E.開心的塗刷

總方案數\(m^n\),任意相鄰格子不同的方案數\(m\times(m-1)^{n-1}\)

作差

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

const ll mod = 1000000007;
ll n , m ;

ll ksm( ll x , ll y )
{
    ll res = 1;
    while( y )
    {
        if( y & 1 ) res = ( res * x ) % mod;
        y >>= 1;
        x = ( x * x ) % mod;
    }
    return res;
}

int main()
{
    cin >> n >> m ;
    m %= mod;
    cout << ( ksm( m , n ) - m * ksm( m - 1 , n - 1 ) % mod + mod ) % mod << endl;
    return 0;
}

F.兼職數靶

打個表就行

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

int n , cnt;
int point[20][20] = {   {1,1,1,1,1,1,1,1,1,1,1,1,1},
                    {1,2,2,2,2,2,2,2,2,2,2,2,1},
                    {1,2,2,2,2,2,2,2,2,2,2,2,1},
                    {1,2,2,3,3,3,3,3,3,3,2,2,1},
                    {1,2,2,3,3,3,3,3,3,3,2,2,1},
                    {1,2,2,3,3,4,4,4,3,3,2,2,1},
                    {1,2,2,3,3,4,4,4,3,3,2,2,1},
                    {1,2,2,3,3,4,4,4,3,3,2,2,1},
                    {1,2,2,3,3,3,3,3,3,3,2,2,1},
                    {1,2,2,3,3,3,3,3,3,3,2,2,1},
                    {1,2,2,2,2,2,2,2,2,2,2,2,1},
                    {1,2,2,2,2,2,2,2,2,2,2,2,1},
                    {1,1,1,1,1,1,1,1,1,1,1,1,1} };

bool get()
{
    char ch = getchar();
    while( ch != '.' && ch != '#' ) ch = getchar();
    return ( ch == '#' ? 1 : 0 );
}

int main()
{
    for( ; ; )
    {
        cin >> n;
        if( n == 0 ) exit(0);
        cnt = 0;
        for( int i = 1 ; i <= 13 ; i ++ )
        {
            for( int j = 1 ; j <= 13 ; j ++ )
            if( get() ) cnt += point[ i - 1 ][ j - 1 ];
        }
        printf( "%.2lf\n" , 1.0 * cnt / n );
    }
    return 0;
}

G.卡牌遊戲

只記錄AliceBob多贏了幾局即可

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


int n , t;
string a , b;
int main()
{
    cin >> n;
    for( int i = 1 ; i <= n ; i ++ )
    {
        cin >> a >> b;
        if( ( a == "Jin" && b == "Mu" ) || ( a == "Mu" && b == "Tu" ) || ( a == "Tu" && b == "Shui" ) || ( a == "Shui" && b == "Huo" ) || ( a == "Huo" && b == "Jin" ) ) t ++;
        if( ( b == "Jin" && a == "Mu" ) || ( b == "Mu" && a == "Tu" ) || ( b == "Tu" && a == "Shui" ) || ( b == "Shui" && a == "Huo" ) || ( b == "Huo" && a == "Jin" ) ) t --;
    }
    if( t > 0 ) cout << "Alice\n";
    else if( t < 0 ) cout << "Bob\n";
    else cout << "Draw\n";
    return 0;
}

H.Hungry!

簽到題輸入\(n\)輸出\(n\)gu...和一句話,正式賽大家應該都是被英文勸退了吧

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


int m;
string s;
unordered_map< char , char > h;

int main()
{
    while(cin>>m)
    {
        for( int i = 1 ; i <= m ; i ++ ) cout << "gu...";
        cout<< "\nThe story is so boring. And I am so hungry!\n";
    }
}

I.快餓死的XzzF

動態規劃,記憶化搜尋也行吧

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

int n ;
long long f[25][2];

int main()
{
    cin >> n;
    f[1][0] = f[1][1] = 1;
    for( int i = 2 ; i <= n ; i ++ ) f[i][1] = f[i-1][0] + f[i-1][1] , f[i][0] = f[i-1][1];
    cout << f[n][0] + f[n][1] << endl;
    return 0;
}

J.小豬佩奇練打字

做個簡單的雜湊即可

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


int m;
string s;
unordered_map< char , char > h;

int main()
{
    cin >> s;
    for( char i = 'a' ; i <= 'z' ; i ++ ) h[i] = i;
    cin >> m;
    for( char x , y ; m ; m -- )
    {
        cin >> x >> y;
        swap( h[x] , h[y] );
    }
    for( auto i : s ) cout << h[i];
    return 0;
}

K.免費WIFI

貪心的選擇即可

似乎有優先佇列做法,我每次sort暴力跑也過了

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


long long q[10005] , n , cnt = 1 , m;
pair< long , long > t[10005];

int main()
{
    cin >> n >> m;
    for( int i = 1 ; i <= n ; i ++ ) cin >> t[i].l >> t[i].r;
    sort( t + 1 , t + 1 + n );
    for( int i = 1 , f ; i <= n ; i ++ )
    {
        f = 0;
        for( int j = 1 ; j <= cnt && !f ; j ++ ) if( t[i].l > q[j] ) q[j] = t[i].r , f = 1;
        if( !f ) q[ ++ cnt ] = t[i].r;
        sort( q + 1 , q + 1 + cnt );
    }
    cout << cnt / m + ( cnt % m ? 1 : 0 ) << endl;
    return 0;
}