電子科技大學實驗中學PK賽(一)比賽題解

比賽來源:第十四屆重慶大學程序設計大賽暨西南地區高校邀請賽現場初賽ios

比賽地址:http://qscoj.cn/contest/24/c++

A. Comb 自述函數

分析:統計ACM在題目描述中出現的次數,認真數一遍就行了,答案就是比賽標題中的14.ui

官方標程:spa

#include <cstdio>

int main() {
    puts("14");
    return 0;
}

個人AC代碼:設計

#include<stdio.h>
int main()
{
    printf("14\n");
    return 0;
}

B. Comb 數學code

分析:超級水題,咱們知道5的任何正數次方都是5,惟一的坑就是5的0次方是1,只要加一個判斷就行。blog

官方標程:ci

#include <cstdio>

int main() {
    int t; scanf("%d", &t);
    while(t--) {
        int x; scanf("%d", &x);
        printf("%d\n", x ? 5 : 1);
    }
    return 0;
}

個人AC代碼:數學

#include<stdio.h>
int main()
{
    int T,x;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&x);
        if (x) printf("5\n");
        else printf("1\n");
    }
    return 0;
}

C. Comb 找零

分析:題目裏說Comb裏的每一個錢袋子都是2的x次冪,因此要正好湊成n數量的錢,就得將n轉化爲二進制統計其中1的數量,就是最少的錢袋數。固然,一個裝2的x次冪的錢袋也能夠拆成2個裝2的x-1次冪的錢袋,但那樣的話會讓錢袋的數量更多。因此統計n轉化成二進制其中1的數量就是最佳答案。注意n的數據範圍爲10^19,就比long long大了一點,我想用double發現精度會有問題,而後寫了個高精度過了這個題,看了官方標程纔想起還有unsigned long long這種東西。官方標程中的__builtin_popcountll(x)這個函數就是返回x轉化成二進制後其中1的個數。

官方標程:

#include <cstdio>

int main() {
    int t; scanf("%d", &t);
    while(t--) {
        unsigned long long x; scanf("%llu", &x);
        printf("%d\n", __builtin_popcountll(x));
    }
    return 0;
}

個人AC代碼:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T,i,cnt,len;
    int a[20];
    long long n,j;
    string s,s0;
    cin>>T;
    s0="9223372036854775808";
    while(T--)
    {
        cin>>s;len=s.length();cnt=0;
        memset(a,0,sizeof(a));
        for(i=0;i<len;i++)
            a[len-1-i]=s[i]-48;
        if (len==20 || (len==19 && s>=s0))
        {
            cnt++;
            for(i=0;i<=18;i++)
                a[i]-=s0[18-i]-48;
            for(i=0;i<=18;i++)
            {
                if (a[i]<0) {a[i]+=10;a[i+1]--;}
            }
        }
        j=1e18;n=0;
        for(i=18;i>=0;i--)
        {
            n+=j*a[i];
            j/=10;
        }
        for(i=62;i>=0;i--)
        {
            j=(1ll<<i);
            cnt+=n/j;n%=j;
        }
        printf("%d\n",cnt);
    }
    return 0;
}

D. Comb 尋路

分析:棋盤的大小不大,只有100*100,因此能夠採用BFS的方法,用dp[i][j]記錄點從起點到點(i,j)的最短期,一開始將怪物及怪物周邊的空地標爲-1;將其餘點標爲inf,將起點標爲0,從起點開始BFS.注意從空地到空地須要花費時間1,從空地到牆或從牆到空地須要花費時間2,從牆到牆須要花費時間3.搜索完畢後判斷終點的dp[i][j]值,若是爲-1或inf則輸出「Oh, Comb can't go out」,不然就輸出該答案。

官方標程:

//
//  Created by TaoSama on 2017-05-01
//  Copyright (c) 2017 TaoSama. All rights reserved.
//
#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>

using namespace std;
#define pr(x) cerr << #x << " = " << x << "  "
#define prln(x) cerr << #x << " = " << x << endl
const int N = 1e2 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

int n, m;
char s[N][N];
int f[N][N], in[N][N];

int main() {
#ifdef LOCAL
    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    int t; scanf("%d", &t);
    while(t--) {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++i) scanf("%s", s[i] + 1);

        int sx, sy, tx, ty;
        static const int d[][2] = { -1, 0, 0, -1, 1, 0, 0, 1};
        auto inBound = [&](int x, int y) {
            return x >= 1 && x <= n && y >= 1 && y <= m;
        };
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= m; ++j) {
                if(s[i][j] == 'C') sx = i, sy = j;
                else if(s[i][j] == 'E') tx = i, ty = j;
                else if(s[i][j] == 'M') {
                    for(int k = 0; k < 4; ++k) {
                        int x = i + d[k][0], y = j + d[k][1];
                        if(inBound(x, y) && s[x][y] == '*') s[x][y] = 'X';
                    }
                }
            }
        }

        bool can = true;
        for(int k = 0; k < 4; ++k) {
            int x = sx + d[k][0], y = sy + d[k][1];
            if(inBound(x, y) && s[x][y] == 'M') can = false;
        }
        for(int k = 0; k < 4; ++k) {
            int x = tx + d[k][0], y = ty + d[k][1];
            if(inBound(x, y) && s[x][y] == 'M') can = false;
        }
        if(!can) {puts("Oh, Comb can't go out"); continue;}

        queue<pair<int, int>> q; q.push({sx, sy});
        memset(f, 0x3f, sizeof f);
        memset(in, false, sizeof in);
        f[sx][sy] = 0; in[sx][sy] = true;
        while(q.size()) {
            int x, y; tie(x, y) = q.front(); q.pop();
            in[x][y] = false;
            for(int k = 0; k < 4; ++k) {
                int nx = x + d[k][0], ny = y + d[k][1];
                if(!inBound(nx, ny) || s[nx][ny] == 'X') continue;
                int c = s[nx][ny] == '#' ? 3 : 1;
                if(f[nx][ny] > f[x][y] + c) {
                    f[nx][ny] = f[x][y] + c;
                    if(!in[nx][ny]) in[nx][ny] = true, q.push({nx, ny});
                }
            }
        }
        if(f[tx][ty] == INF) puts("Oh, Comb can't go out");
        else printf("%d\n", f[tx][ty]);
    }

    return 0;
}

個人AC代碼:

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
vector< pair<int,int> > v[10010];
int fx[4]={-1,1,0,0};
int fy[4]={0,0,-1,1};
int main()
{
    int T,n,m,xc,yc,xe,ye,i,j,k,s;
    int x,y,xx,yy,cnt;
    int dp[110][110];
    char c[110][110];
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
                dp[i][j]=inf;
        for(i=0;i<=10000;i++)
            v[i].clear();
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
            {
                cin>>c[i][j];
                if (c[i][j]=='C') {xc=i;yc=j;}
                if (c[i][j]=='E') {xe=i;ye=j;}
            }
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
            {
                if (c[i][j]=='M')
                {
                    dp[i][j]=-1;
                    for(k=0;k<4;k++)
                    {
                        xx=i+fx[k];
                        yy=j+fy[k];
                        if (xx<1 || xx>n || yy<1 || yy>m) continue;
                        if (c[xx][yy]=='#') continue;
                        dp[xx][yy]=-1;
                    }
                }
            }
        if (dp[xc][yc]==-1 || dp[xe][ye]==-1)
        {
            printf("Oh, Comb can't go out\n");
            continue;
        }
        v[0].push_back(make_pair(xc,yc));dp[xc][yc]=0;cnt=0;
        while(1)
        {
            for(i=0;i<v[cnt].size();i++)
            {
                s=1;x=v[cnt][i].first;y=v[cnt][i].second;
                if (dp[x][y]<cnt) continue;
                if (c[x][y]=='#') s++;
                for(j=0;j<4;j++)
                {
                    xx=x+fx[j];yy=y+fy[j];
                    if (xx<1 || xx>n || yy<1 || yy>m) continue;
                    if (dp[xx][yy]==-1) continue;
                    if (c[xx][yy]=='#') s++;
                    if (dp[xx][yy]>cnt+s)
                    {
                        dp[xx][yy]=cnt+s;
                        v[cnt+s].push_back(make_pair(xx,yy));
                    }
                    if (c[xx][yy]=='#') s--;
                }
            }
            if (cnt>=2 && !v[cnt].size() && !v[cnt-1].size() && !v[cnt-2].size()) break;
            cnt++;
        }
        if (dp[i][j]==-1) printf("Oh, Comb can't go out\n");
        else printf("%d\n",dp[xe][ye]);
    }
    return 0;
}
相關文章
相關標籤/搜索