USACO Section 2.4

USACO Section 2.4
The Tamworth Two

/*
    ID: beihai2013
    TASK: ttwo
    LANG: C++
*/
/*
    刚开始想复杂了,想通过记录数组然后求牛或者人经过此点的时间戳来求周期,然后求一个通项
    后面发现这样的讨论不仅复杂,而且容易出现十分多的情况
    然后仔细一想,假设是有人和牛周期的话,他们分别得周期不超过100,联合起来周期肯定不超过100 * 100
    所以设一个周期上限值,如果还没遇到就退出就可以了
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 10 + 2;
const int MAXM = 4 + 1;
//int dp[2][MAXN][MAXN][MAXM];
char g[MAXN][MAXN];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
bool validPos(int x, int y){if(x >= 0 && x < 10 && y >= 0 && y < 10) return true; else return false;}
int x[2], y[2], dir[2];
int main()
{
    freopen("ttwo.in", "r", stdin);
    freopen("ttwo.out", "w", stdout);
    int n = 10;
    for(int i = 0 ; i < 10 ; i++) scanf("%s", g[i]);
    for(int i = 0 ; i < 10 ; i++) {
        for(int j = 0 ; j < 10 ; j++) {
            if(g[i][j] == 'C') x[0] = i, y[0] = j;
            else if(g[i][j] == 'F') x[1] = i, y[1] = j;
        }
    }
    dir[0] = dir[1] = 0;
    int res = 0;
    int T = 100000 + 5;
    int cnt = 0;
    while(T--) {
        if(x[0] == x[1] && y[0] == y[1]) {
            res = cnt;
            break;
        }
         for(int i = 0 ; i < 2 ; i++) {
             int tx = dx[dir[i]] + x[i];
             int ty = dy[dir[i]] + y[i];
             if(validPos(tx, ty) && g[tx][ty] != '*') {
                x[i] = tx, y[i] = ty;
             }
             else {
                dir[i] = (dir[i] + 1) % 4;
             }
         }
         cnt++;
    }

    printf("%d\n", res);
    return 0;
}

Overfencing

/*
    ID: beihai2013
    TASK: maze1
    LANG: C++
*/
/*
    宽搜做迷宫,不过这次是一次朝一个方向跳两格
*/
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pu push
#define fi first
#define se second
typedef pair<int,int> pii;
const int MAXN = 200 + 2;
char g[MAXN * 2 + 1][MAXN * 2 + 1];
int dp[MAXN * 2 + 1][MAXN * 2 + 1], n, m;
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};
queue<pii>que;
bool validPos(int x, int y){if(x >= 0 && x < n && y >= 0 && y < m) return true; else return false;}
int main()
{
    freopen("maze1.in", "r", stdin);
    freopen("maze1.out", "w", stdout);
    while(scanf("%d%d", &m, &n) != EOF) {
        n = n * 2 + 1;
        m = m * 2 + 1;
        getchar();
        for(int i = 0 ; i < n ; i++) {
            cin.getline(g[i], MAXN * 2 + 1);
        }
        memset(dp, -1, sizeof dp);
        while(!que.empty()) que.pop();
        for(int i = 0 ; i < n ; i++) {
            if(g[i][0] == ' ') que.pu(mp(i, 1)), dp[i][1] = 1;
            if(g[i][m - 1] == ' ') que.pu(mp(i, m - 2)), dp[i][m - 2] = 1;
        }
        for(int i = 0 ; i < m ; i++) {
            if(g[0][i] == ' ') que.pu(mp(1, i)), dp[1][i] = 1;
            if(g[n - 1][i] == ' ') que.pu(mp(n - 2, i)), dp[n - 2][i] = 1;
        }

        while(!que.empty()) {
            pii p = que.front(); que.pop();
            for(int i = 0 ; i < 4 ; i++) {
                int tx1 = dx[i] + p.fi;
                int ty1 = dy[i] + p.se;
                if(validPos(tx1, ty1) && g[tx1][ty1] == ' ') {
                    int tx2 = dx[i] + tx1;
                    int ty2 = dy[i] + ty1;
                    if(validPos(tx2, ty2) && g[tx2][ty2] == ' ') {
                        if(dp[tx2][ty2] == -1) {
                            dp[tx2][ty2] = dp[p.fi][p.se] + 1;
                            que.pu(mp(tx2, ty2));
                        }
                    }
                }
            }
        }

        int res = -1;
        for(int i = 0 ; i < n ; i++) {
            for(int j = 0 ; j < m ; j++) {
                res = max(res, dp[i][j]);
            }
        }

        printf("%d\n", res);
    }
    return 0;
}

Cow Tours

/*
    ID: beihai2013
    TASK: cowtour
    LANG: C++
*/
/*
    每个点存一个连通块,连通块持有信息为连通块包含的点、连通块直径
    然后连接两个连通块时,假设连通块1通过点A连接连通块2的点B
    得到的新答案为(连接A、B两点距离+连通块1内距A最远距离+连通块2内距B最远距离)
    此新答案还要与原A、B的直径做比较
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 150 + 5;
int n, vis[MAXN], g[MAXN][MAXN];
double x[MAXN], y[MAXN];
int bccno[MAXN], bcccnt;
char str[MAXN];
double dep[MAXN];
double r[MAXN], far[MAXN];
vector<int> bcc[MAXN];
queue<int> que;
double cal(double x1, double y1, double x2, double y2){return sqrt(1.0 * (x1 - x2) * (x1 - x2) + 1.0 * (y1 - y2) * (y1 - y2));}
void dfs(int u, int num)
{
    bccno[u] = num;
    bcc[num].push_back(u);
    for(int i = 0 ; i < n ; i++) {
        if(g[u][i] == 1 && bccno[i] == 0) {
            dfs(i, num);
        }
    }
}
double bfs(int u)
{
    double res = 0;
    while(!que.empty()) que.pop();
    for(int i = 0 ; i < (int)bcc[bccno[u]].size() ; i++) {
        int v = bcc[bccno[u]][i];
        dep[v] = -1.0, vis[v] = 0;
    }
    dep[u] = 0; vis[u] = 1;
    que.push(u);
    while(!que.empty()) {
        int v = que.front(); que.pop(); vis[v] = 0;
//        if(u == 6) {
//            printf("v = %d, dep = %f\n", v, dep[v]);
//        }
        for(int i = 0 ; i < n ; i++) {
            if(g[v][i] == 0) continue;
            double dis = cal(x[v], y[v], x[i], y[i]);
            if(dep[i] > dep[v] + dis || dep[i] == -1.0) {
                dep[i] = dep[v] + dis;
                if(vis[i] == 0) {
                    vis[i] = 1;
                    que.push(i);
                }
            }
        }
    }
    ///此处需要单独写,之前在上面写WA了
    for(int i = 0 ; i < (int)bcc[bccno[u]].size() ; i++) res = max(res, dep[bcc[bccno[u]][i]]);
//    if(u == 6)
//    system("pause");
    return res;
}
double solve(int u, int v)
{
//    double t1 = bfs(u);
//    double t2 = bfs(v);
    double t3 = cal(x[u], y[u], x[v], y[v]);
    return max(r[bccno[u]], max(far[u] + far[v] + t3, r[bccno[v]]));
}
int main()
{
    freopen("cowtour.in", "r", stdin);
    freopen("cowtour.out", "w", stdout);
    while(scanf("%d", &n) != EOF) {
        for(int i = 0 ; i < n ; i++) scanf("%lf%lf", x + i, y + i);
        for(int i = 0 ; i < n ; i++) {
            scanf("%s", str);
            for(int j = 0 ; j < n ; j++) {
                if(str[j] == '0') g[i][j] = 0;
                else g[i][j] = 1;
            }
        }

        memset(bccno, 0, sizeof bccno);
        bcccnt = 0;
        for(int i = 0 ; i < n ; i++) {
            if(bccno[i]) continue;
            else {
                bcc[++bcccnt].clear();
                dfs(i, bcccnt);
            }
        }
        memset(r, 0, sizeof r);
        for(int i = 0 ; i < n ; i++) {
            far[i] = bfs(i);
            r[bccno[i]] = max(r[bccno[i]], far[i]);
        }
        double res = 1e5 * 1e5 * 1e5;
        for(int i = 0 ; i < n ; i++) {
            for(int j = i + 1 ; j < n ; j++) {
                if(bccno[i] == bccno[j]) continue;
//                double temp = solve(i, j);
//                printf("i = %d, j = %d, temp = %f\n", i, j, temp);
//                system("pause");
                res = min(res, solve(i, j));
            }
        }
        printf("%.6f\n", res);
    }
    return 0;
}

Bessie Come Home

/*
    ID: beihai2013
    TASK: comehome
    LANG: C++
*/
/*
    简单最短路
*/
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
typedef pair<int,int> pii;
const int MAXN = 100 + 5;
vector<pii>e[MAXN];
int toI(char c)
{
    if(c >= 'A' && c <= 'Y') return c - 'A' + 1;
    else if(c == 'Z') return 0;
    else return c - 'a' + 26;
}
char s1[5], s2[5];
int dep[MAXN], vis[MAXN], m;
queue<int>que;
int main()
{
//    printf("toI(z) = %d, toI(Z) = %d, toI(Y) = %d, toI(a) = %d\n", toI('z'), toI('Z'), toI('Y'), toI('a'));
    freopen("comehome.in", "r", stdin);
    freopen("comehome.out", "w", stdout);
    while(scanf("%d", &m) != EOF) {
        for(int i = 0 ; i < MAXN ; i++) e[i].clear();
        for(int i = 0 ; i < m ; i++) {
            scanf("%s%s", s1, s2);
            int w;  scanf("%d", &w);
            int u = toI(s1[0]);
            int v = toI(s2[0]);
            e[u].pb(mp(v, w));
            e[v].pb(mp(u, w));
        }

        for(int i = 0 ; i < MAXN ; i++) dep[i] = -1, vis[i] = 0;
        while(!que.empty()) que.pop();
        que.push(0), vis[0] = 1, dep[0] = 0;
        while(!que.empty()) {
            int u = que.front(); que.pop();
            vis[u] = 0;
            for(int i = 0 ; i < (int)e[u].size() ; i++) {
                pii p = e[u][i];
                if(dep[p.fi] == -1 || dep[p.fi] > dep[u] + p.se) {
                    dep[p.fi] = dep[u] + p.se;
                    if(vis[p.fi] == 0) {
                        vis[p.fi] = 1;
                        que.push(p.fi);
                    }
                }
            }
        }

        int res = -1;
        int re = 1;
        for(int i = 1 ; i < 26 ; i++) {
            if(dep[i] != -1 && (res == -1 || res > dep[i]))
                res = dep[i], re = i;
        }
        printf("%c %d\n", 'A' + re - 1, res);
    }
    return 0;
}

Fractions to Decimals

/*
    ID: beihai2013
    TASK: fracdec
    LANG: C++
*/
/*
    找循环节就可以,调格式调了一段时间
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 5;
int dp[MAXN];
int out[MAXN], outcnt;
int pre;
char res[MAXN];
int main()
{
    freopen("fracdec.in", "r", stdin);
    freopen("fracdec.out", "w", stdout);
    int n, d;
    while(scanf("%d%d", &n, &d) != EOF) {
        pre = n / d;
        n = n % d;
        n *= 10;
        memset(dp, 0, sizeof dp);
        int flag = 0;
        outcnt = 0;
        int rear = 1, head = 1;
        while(1) {
//            printf("n = %d, outcnt = %d\n", n, outcnt);
//            printf("out = "); for(int i = 1 ; i <= outcnt ; i++) printf("%d", out[i]);
//            printf("\n");
//            system("pause");
            if(n == 0) {
                rear = outcnt;
                head = outcnt + 1;
                flag = 1;
                break;
            }
            if(dp[n]) {
                head = dp[n];
                rear = outcnt;
                break;
            }
            else {
                dp[n] = ++outcnt;
                out[outcnt] = n / d;
                n = n % d;
                n = n * 10;
            }
        }
//        printf("head = %d, rear = %d, outcnt = %d, pre = %d, flag = %d\n", head, rear, outcnt, pre, flag);
        int rescnt = 0;
        if(pre == 0) res[rescnt++] = '0' + 0;
        else {
            while(pre) {
                res[rescnt++] = pre % 10 + '0';
                pre = pre / 10;
            }
            for(int i = 0 ; i < rescnt / 2 ; i++) swap(res[i], res[rescnt - 1 - i]);
        }
        res[rescnt++] = '.';
        if(outcnt == 0) res[rescnt++] = '0';
        for(int i = 1 ; i < head ; i++) {
            res[rescnt++] = out[i] + '0';
        }
        if(flag == 0) {
            res[rescnt++] = '(';
            for(int i = head ; i <= rear ; i++) res[rescnt++] = out[i] + '0';
            res[rescnt++] = ')';
        }
        for(int i = 0 ; i < rescnt ; i++) {
            printf("%c", res[i]);
            if(i % 76 == 75 && i != 0) printf("\n");
        }
        printf("\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值