1. 程式人生 > >ACdream區域賽指導賽之手速賽系列(4)題解

ACdream區域賽指導賽之手速賽系列(4)題解

 Acdream的這場比賽真真到達了“區域賽之手速賽”的水平。

不過還是略顯自己的弱渣之水平。

A題。染色法判二分圖,妥妥的。一開始讀錯題。。WA了一發。

對於這道題目的定位為:模板/經典題目。這也是所謂“區域賽手速題”吧。。

Code:

/*
* this code is made by creat2012
* Problem: 1056
* Verdict: Accepted
* Submission Date: 2014-08-08 19:40:43
* Time: 24MS
* Memory: 1824KB
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <string>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define CLR(arr, val) memset(arr, val, sizeof(arr))
const int N = 203;
bool vis[N];
int color[N];
vector<int> Map[N];
 
bool bfs(int s){
    queue<int> q;
    q.push(s);color[s]=1;
    while(!q.empty()){
        int now=q.front();
        q.pop();
        if(!vis[now]){
        int len=Map[now].size();
        for(int i=0;i<len;i++){
            int des=Map[now][i];
            q.push(des);
            if(color[des]==-1)
            color[des]=color[now]==0?1:0;
            else {
                if(color[des]==color[now]) return false;
                else continue;
            }
        }
        vis[now]=true;
        }
    }
    return true;
}
 
int main(){
    int T, k = 0;
    scanf("%d", &T);
    while(T --){
        CLR(color,-1);CLR(vis,0);
        CLR(Map,0);
        map<string, int> m;
        int n, no = 0, x, y;
        string st1, st2;
        scanf("%d", &n);
        for(int i = 1; i <= n; i ++){
            cin >> st1 >> st2;
            if(m.count(st1) == 0) m[st1] = ++ no;
            x = m[st1];
            if(m.count(st2) == 0) m[st2] = ++ no;
            y = m[st2];
            Map[x].push_back(y);
            Map[y].push_back(x);
        }
//        printf("%d\n", no);
//        for(int i = 1; i <= no; i ++){
//            for(int j = 0; j < Map[i].size(); j ++)
//            printf("%d ", Map[i][j]);
//            printf("\n");
//        }
        bool flag = true;
        printf("Case #%d: ", ++k);
        for(int i = 1; i <= no; i ++){
            if(!vis[i]){
                if(!bfs(i)) flag = false;
            }
        }
        if(!flag) puts("No");
        else puts("Yes");
        for(int i = 1; i <= no; i ++) Map[i].clear();
    }
    return 0;
}


B題。說一個草坪(n*m的矩陣表示)初始時候全部為100m。一個割草機沒次可以垂直進入割草,每次寬度為1m(也就是一個矩陣的一行/一列)。問一種狀態是否可以是該割草機割的。

這道題的定位為,小型想法題。有好的想法,處理起來就很easy了。

對於該題的思路為:若一個位置的草的高度小於該位置的同行,同列的較小者。為不符合的狀態。

Code:

/*
* this code is made by creat2012
* Problem: 1044
* Verdict: Accepted
* Submission Date: 2014-08-09 11:24:40
* Time: 8MS
* Memory: 1088KB
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
 
const int N = 105;
int main(){
    int T, k = 0;
    scanf("%d", &T);
    while(T --){
        int n, m, map[N][N];
        scanf("%d %d", &n, &m);
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= m; j ++)
            scanf("%d", &map[i][j]);
        }
        int l[N], c[N];
        for(int i = 1; i <= n; i ++){
            int lmax = -1;
            for(int j = 1; j <= m; j ++)
            lmax = max(map[i][j], lmax);
            l[i] = lmax;
        }
        for(int i = 1; i <= m; i ++){
            int cmax = -1;
            for(int j = 1; j <= n; j ++)
            cmax = max(map[j][i], cmax);
            c[i] = cmax;
        }
        bool flag = true;
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= m; j ++)
            if(map[i][j] < min(l[i], c[j]))
            flag = false;
        }
        printf("Case #%d: ", ++ k);
        if(flag) puts("YES");
        else puts("NO");
    }
    return 0;

C題:一個物理問題。可以得到一個公司。ans = asin((g * d) / (v * v) * 90.0 / PI);

很easy 的一個題目。本來大家都以為1A,沒有問題。

可以如果我們注意到資料範圍的話:1 ≤ T ≤ 4500   1 ≤ V ≤ 300    1 ≤ D ≤ 10000

如果思考認真的話,我們可以看到,asin();中的值是可以為>1的。但是,我們知道這是不合法的。

Code:

/*
* this code is made by creat2012
* Problem: 1118
* Verdict: Wrong Answer
* Submission Date: 2014-08-09 11:53:24
* Time: 4MS
* Memory: 1220KB
*/
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
 
const double PI = acos(-1);
const double g = 9.8;
int main(){
    int T, k = 0;
    scanf("%d", &T);
    while(T --){
        double v, d;
        scanf("%lf %lf", &v, &d);
        double ans = g * d / v / v;
        ans = ans > 1.0 ? 1.0 : ans;
        printf("Case #%d: %.7lf\n", ++ k,  asin(ans) * 90.0 / PI);
    }
    return 0;
}

D題,稍後再更新。

E題,判斷一個棋盤的狀態。這也是我們常玩遊戲的一部分的實現。

這道題目的定位:思路的全面性。考察你的思路是否全面。

根據邀請賽的經驗,往往會有這方面的考察。一定要注意。。!!

處理的好了。很easy。

Code:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

const int N = 5;
char map[N][N];
char Judge(){
    char now ;
    int cnt ;
    for(int i = 1; i <= 4; i ++){
        now = map[i][1];
        cnt = 1;
        for(int j = 2; j <= 4; j ++){
            if(now == 'T') now = map[i][2];
            if(map[i][j] == now ||map[i][j] == 'T') cnt ++;
        }
        if(cnt == 4 && now != '.') return now;
    }
    for(int i = 1; i <= 4; i ++){
        now = map[1][i];
        cnt = 1;
        for(int j = 2; j <= 4; j ++){
            if(now == 'T') now = map[2][i];
            if(map[j][i] == now ||map[j][i] == 'T') cnt ++;
        }
        if(cnt == 4 && now != '.') return now;
    }
    now = map[1][1];
    cnt = 1;
    for(int i = 2; i <= 4; i ++){
        if(now == 'T') now = map[2][2];
        if(map[i][i] == now  ||map[i][i] == 'T') cnt ++;
        if(cnt == 4 && now != '.') return now;
    }
    now = map[1][4]; cnt = 1;
    for(int i = 2; i <= 4; i ++){
        if(now == 'T') now = map[2][3];
        if(map[i][5 - i] == now  ||map[i][5 - i] == 'T') cnt ++;
        if(cnt == 4 && now != '.') return now;
    }

    for(int i = 1; i <= 4; i ++){
        for(int j = 1; j <= 4; j ++)
        if(map[i][j] == '.') return 'G';
    }
    return 'D';
}
int main(){
    int T, k = 1;
    scanf("%d", &T);
    while(T --){
        getchar();
        for(int i = 1; i <= 4; i ++){
            for(int j = 1; j <= 4; j ++)
            scanf("%c", &map[i][j]);
            getchar();
        }
        printf("Case #%d: ", k ++);
        char c = Judge();
        if(c == 'O') puts("O won");
        else if(c == 'X') puts("X won");
        else if(c == 'D') puts("Draw");
        else puts("Game has not completed");
    }
    return 0;
}

程式碼寫 的很挫。。。。。- - !還需要多些程式碼.。。。。