SMU 2018 校赛题解

A dreamstart的催促

快速幂模板题

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

const int mod = 10000019;
int n , ans = 0;

int 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;
    for( int i = 1 , x ; i <= n ; i ++ )
    {
        cin >> x;
        ans = ( ans + ksm( x , i ) ) % mod;
    }
    cout << ans << endl;
    return 0;
}

B TRDD got lost again

BFS题目,一次跳两格即可如果跳一格有障碍,则不能跳这一步

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

const int N = 6005;
const int dx[] = { 1 , -1 , 0 , 0 } , dy[]={ 0 , 0 , 1 , -1 };
int n , m , tx , ty , nx , ny , fx , ffx , fy , ffy ;
int step ;
bool vis[N][N];
queue< pair< pair< int, int> , int > > q;


int main()
{
    cin >> n >> m;
    getchar();
    n = 2 * n + 1 , m = 2 * m + 1;
    char ch;
    for( int i = 1 ; i <= n ; i ++ )
    {
        for( int j = 1 ; j <= m ; j ++ )
        {
            ch = getchar();
            if( ch == 'S' ) q.push( { { i , j } , 1 } ) , vis[i][j] = 1;
            else if( ch == 'T' ) tx = i , ty = j;
            else if( ch != ' ' ) vis[i][j] = 1;
        }
        getchar();
    }
    while( !q.empty() )
    {
        nx = q.front().first.first , ny = q.front().first.second , step = q.front().second ; q.pop();
        if( nx == tx && ny == ty ) { cout << step << endl; return 0; }
        for( int i = 0 ; i < 4 ; i ++ )
        {
            fx = nx + dx[i] , fy = ny + dy[i] , ffx = nx + ( dx[i] << 1 ), ffy = ny + ( dy[i] << 1 );
            if( ffx < 1 || ffy < 1 || ffx > n || ffy > m ) continue;
            if( vis[fx][fy] || vis[ffx][ffy] ) continue;
            q.push( { { ffx , ffy } , step + 1 } ) , vis[ffx][ffy] = 1;
        }
    }
    cout << "TRDD Got lost...TAT\n";
}

C Company

DFS统计子树大小即可

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

const int N = 2e5 + 5;
int n , k , son[N];
bool vis[N];
vector< int > e[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;
}

void dfs( int x )
{
    vis[x] = 1;
    for( auto v : e[x] )
    {
        if( vis[v] ) continue;
        dfs( v ) , son[x] += son[v];
    }
    return ;
}
int main()
{
    n = read() , k = read();
    for( int i = 1 , x ; i <= n ; i ++ ) x = read() , son[i] = ( x <= k );
    for( int i = 1 , u , v ; i < n ; i ++ ) u = read() , v = read() , e[u].push_back(v) , e[v].push_back(u);
    dfs(1);
    for( int i = 1 ; i <= n ; i ++ ) printf("%d " , son[i] );
    printf("\n");
}

D >A->B->C-

签到题,由于环的大小为三才成立,根本不用DFS

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

int n , a[5005] , b , c ;
bool v[5005];

int main()
{
    cin >> n;
    for( int i = 1 ; i <= n ; i ++ ) cin >> a[i];
    for( int i = 1 ; i <= n ; i ++ )
    {
        b = a[i];
        c = a[b] ;
        if( i == b || b == c || c == i ) continue;
        if( i == a[c] )
        {
            cout << "YES\n";
            return 0;
        }
    }
    cout << "NO\n";
    return 0;
}

E PPY的字符串

模拟题,重复做n次就好,字符转数字的可以用数组表示

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


int n;
string a , b;
const char num[] = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9'};

int main()
{
    cin >> a >> n;
    n --;
    while( n -- )
    {
        for( int i = 0 , j , t ; i < a.size() ; i = j )
        {
            for( j = i + 1 ; a[i] == a[j] ; j ++ );
            t = j - i;
            while( t ) b +=  num[ ( t % 10 ) ] , t /= 10;
            b += a[i];
        }
        a = b , b = "";
    }
    cout << a.size() << " " << a << endl;
}

F 集训队脱单大法:这是一道只能由学姐我自己出数据的水题

前缀和,枚举切开的点

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

const int N = 1e5+5;
int n , a[N] , x[N] , y[N] , res ;

int main()
{
    cin >> n;
    for( int i = 1 ; i <= n ; i ++ ) cin >> a[i];
    for( int i = 1 ; i <= n ; i ++ ) x[i] = max( x[ i - 1 ] , a[i] );
    for( int i = n ; i >= 1 ; i -- ) y[i] = max( y[ i + 1 ] , a[i] );
    for( int i = 1 ; i < n ; i ++ ) res = max( res , abs( x[i] - y[ i + 1 ] ) );
    cout << res << endl;
    return 0;
}

G 不想再WA了

DP题目,但是难得写,就随手写了个搜索,担心TLE,就打了个表,但实际上我的DFS似乎可以直接过

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

int res[] ={ 0 , 3 , 8 , 21 , 55 , 144 , 377 , 987 , 2584 , 6765 , 17711 };

int main()
{
    int t , n;
    cin >> t;
    for( int i = 1 ; i <= t ; i ++ )
    {
        cin >> n;
        cout << res[n] << endl;
    }
}

下面是DFS打表格代码

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

int n , cnt;

int dfs( int dep , int last )
{
    if( dep == n + 1 )
    {
        cnt ++;
        return 0;
    }
    for( int i = 1 ; i <= 3 ; i ++ )
    {
        if( i == 1 && last == 3 ) continue;
        dfs( dep + 1 , i );
    }
}
int main()
{
    for( n = 1 ; n <= 10 ; n ++ )
    {
        cnt = 0;
        dfs( 1 , 0 );
        cout << cnt << endl;
    }
}

H Ricky’s RealDan’s Ricky

只有当只有一堆,且为偶数时Ricky才会赢,不然其他任何情况RealDan都可以通过有限次操作把一堆娃娃变成奇数。此时Ricky则无法取胜

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

const int N = 100005;
int n , a[N];

void slove()
{
    cin >> n;
    for( int i = 1 ; i <= n ; i ++ ) cin >> a[i];
    if( n == 1 && a[1] % 2 == 0 ) puts("Ricky is Winner");
    else puts("RealDan is Winner");
}

int main()
{
    int t;
    cin >>t;
    while( t -- ) slove();
}

I 小A的期末作业

签到题目

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

int main()
{
    int n;
    cin >> n;
    for( int i = 0 ; i < n ; i ++ )
    {
        for( int j = 1 ; j <= i ; j ++ ) cout << ' ';
        for( int j = 1 ; j <= n ; j ++ ) cout << '*';
        cout << '\n';
    }
    for( int i = n - 2 ; i >= 0 ; i -- )
    {
        for( int j = 1 ; j <= i ; j ++ ) cout << ' ';
        for( int j = 1 ; j <= n ; j ++ ) cout << '*';
        cout << '\n';
    }
    return 0;
}

J 怪盗基德 & 月之瞳宝石

排序找到每个星体最近的能源体,并取最大值,查找能源体可以用二分

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

const int N = 1e5+5;
long long n , m , a[N] , b[N] , res = 0;

int main()
{
    cin >> n >> m;
    for( int i = 1 ; i <= n ; i ++ ) cin >> a[i];
    for( int i = 1 ; i <= m ; i ++ ) cin >> b[i];
    sort( b + 1 , b + 1 + m );
    for( int i = 1 , l ; i <= n ; i ++ )
    {
        l = lower_bound( b + 1 , b + 1 + m , a[i] ) - b;
        if( l == 1 ) res = max( res , b[l] - a[i] );
        else if( l == m + 1 ) res = max( res , a[i] - b[m] );
        else res = max( res , min( b[l] - a[i] , a[i] - b[ l - 1 ] ) );
    }
    cout << res << endl;
}

K 正方体

签到题目

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


int a[4][6] , x , y ;

void slove()
{
    for( int i = 1 ; i <= 3 ; i ++ )
    {
        for( int j = 1 ; j <= 4 ; j ++ ) cin >> a[i][j];
    }
    for( int i = 1 ; i <= 4 ; i ++ )
    {
        if( a[1][i] ) x = a[1][i];
        if( a[3][i] ) y = a[3][i];
    }
    if( x != y || a[2][1] != a[2][3] || a[2][2] != a[2][4] ) cout << "No!\n";
    else cout << "Yes!\n";
}


int main()
{
    int t;
    cin >> t;
    for( int i = 1 ; i <= t ; i ++ )
    {
        slove();
        if( i % 50 == 0 ) cout <<"\n";
    }

    return 0;
}

L 简单的分数

小学数学?通分再约分喽

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

int gcd( int x , int y ) { return ( y ? gcd(  y  , x % y ) : x ); }

void slove()
{
    int op , a , b , c , d ,e;
    cin >> op >> a >> b >> c >> d;
    a *= d , c *= b;
    if( op ) a += c;
    else a -= c;
    b *= d;
    e = gcd( a , b );
    a /= e , b /= e;
    if( b < 0 ) b = -b , a = -a;
    cout << a <<"/" << b << endl;
}

int main()
{
    int t; cin >> t;
    while( t -- ) slove();
    return 0;
}

M HJ浇花

差分模板

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


const int N = 1e6 + 5;
int n , a[N] , m , cnt[N] , t ;


int main()
{
    cin >> n;
    for( int i = 1 , l , r ;  i <= n ; i ++ )
    {
        cin >> l >> r ;
        a[l] ++ , a[ r + 1 ] -- ;
        m = max( m , r );
    }
    for( int i = 1 ; i <= m ; i ++ ) a[i] += a[ i - 1 ];
    for( int i = 0 ; i <= m ; i ++ ) cnt[ a[i] ] ++ , t = max( t , a[i] );
    for( int i = 1 ; i <= n ; i ++ ) cout << cnt[i] << " ";
    cout << endl;
}
上一篇:找到1-n个整数中的质数


下一篇:程序猿迷惑行为大赏