美文网首页JinxiSui - SDUST ACMer
2017 ICPC North American Qualifi

2017 ICPC North American Qualifi

作者: JinxiSui | 来源:发表于2018-10-21 18:29 被阅读0次

A - Birthday Cake

Kattis - birthdaycake

题意:给出一个蛋糕,一些糖果的坐标,一些切割线的ax+by=c直线方程。问这些切割线是否能把蛋糕恰好分成n块且每一块有且仅有一块糖果。

B - Bumped!

Kattis - bumped
题意:有n (0<n≤50000)个城市,m(0≤m≤150000)条公路,f(0≤f≤1000)个航班,起点s,终点t。公路双向可通过,航班单向,且有一次机票免费的机会。城市从0开始编号。
思路:跑f+1遍dijkstra,每次放进去一个免费航班,取距离d[t]最小值。复杂度f*nlogn
AC代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;
typedef long long ll;

int n, m, f, s, t;
const int maxn = 5e4+5;
const int maxm = 1e6+5;
const int maxf = 1005;
const ll INF = 0x3f3f3f3f3f3f3f3f;
struct edge {
    int to, cost;
};
vector<edge> g[maxn];
typedef pair<int, int> P;
ll d[maxn];

void dij() {
    priority_queue<P, vector<P>, greater<P> > que;
    for(int i = 0; i < n; ++i) {
        d[i] = INF;
    }
    d[s] = 0;
    que.push(make_pair(0, s));
    int v;
    while(!que.empty()) {
        P pp = que.top();
        que.pop();
        v = pp.second;
        for(int i = 0; i < g[v].size(); ++i) {
            edge e = g[v][I];
            if(d[v] + e.cost < d[e.to]) {
                d[e.to] = d[v] + e.cost;
                que.push(make_pair(d[e.to], e.to));
            }
        }
    }
}

int main() {
    int fr_, to_, cst_;
    scanf("%d%d%d%d%d", &n, &m, &f, &s, &t);
    for(int i = 0; i < m; ++i) {
        scanf("%d%d%d", &fr_, &to_, &cst_);
        g[fr_].push_back((edge){to_, cst_});
        g[to_].push_back((edge){fr_, cst_});
    }
    dij();
    ll ans = d[t];
    //cout << ans << endl;
    for(int i = 0; i < f; ++i) {
        scanf("%d%d", &fr_, &to_);
        g[fr_].push_back((edge){to_, 0});
        dij();
        ans = min(ans, d[t]);
        g[fr_].erase(g[fr_].end()-1);
    }
    printf("%lld\n", ans);
    return 0;
}

C - Canonical Coin Systems

Kattis - canonical
题意:有不同面值的硬币,若组成一种面额的贪心解即最优解,输出canonical,否则输出non-canonical。
如集合{1,3,4},为了组成面值6,贪心解是4+1+1(3枚硬币),但最优解应该是3+3(2枚硬币)。
思路:队友做的,按照贪心解跑一遍结果,然后再用背包跑一遍最优解,比对,若有不同则为non。
AC代码

# include <iostream>
# include <cstring>

using namespace std;

const int MAX = 1e6;
const int INF = 0x3f3f3f3f;

int n;
int dp[2][MAX * 2 + 20];
int coin[105];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    while(cin >> n)
    {
        for(int i = 0; i < n; I++)
        {
            cin >> coin[i];
        }

        bool right = true;
        memset(dp, INF, sizeof(dp));
        dp[0][0] = dp[1][0] = 0;
        int maxn = 2 * coin[n - 1] + 10;
        for(int i = 1, j; i < maxn; I++)
        {
            for(j = 0; j < n; j++)
            {
                if(coin[j] > i)
                    break;
                dp[0][i] = min(dp[0][i], dp[0][i - coin[j]] + 1);
            }
            dp[1][i] = dp[1][i - coin[j - 1]] + 1;
            if(dp[1][i] != dp[0][I])
            {
                right = false;
                break;
            }
        }

        if(right)
        {
            cout << "canonical" << endl;
        }
        else
        {
            cout << "non-canonical" << endl;
        }
    }
}

D - Cat and Mice

Kattis - catandmice

E - Company Picnic

Kattis - companypicnic

题意:一颗树表示一个公司的上下级关系,现在这个公司要举行一次娱乐活动,两个人各自一条腿绑在一起跑步,那么两个人的速度就是那个跑得慢的人的速度,一个人只能和他的父节点或者子节点组成一组。现在要尽可能多的组成小组,并且让平均速度尽量大。输出组数和最大平均速度。

E - Company Picnic

思路:比赛最后一道题,想用KM匹配做来着,后来感觉不对,又暴的没暴出来。赛后看好像是树形dp。待补。

F - GlitchBot

Kattis - glitchbot
题意:一个机器人,从(0,0)点出发,初始朝向为y轴正方向,首先告诉你目标位置(x,y),给你n条指令,Right是右转,Left左转,Forward朝前走。现在要改变一条指令使得机器人走到目标位置。
思路:模拟即可

# include <iostream>
# include <string>

using namespace std;

const int MAX = 60;
const int f = -1;
const int l = 0;
const int u = 1;
const int r = 2;
const int d = 3;
const int cx[] = {-1, 0, 1, 0};
const int cy[] = {0, 1, 0, -1};

int ex, ey, n;

struct Step
{
    int oper;
    int state;
    int x, y;
};
Step step[MAX];

bool walk(int x, int y, int number, int state)
{
    for(int i = number; i < n; I++)
    {
        if(step[i].oper == f)
        {
            x += cx[state];
            y += cy[state];
        }
        else if(step[i].oper == r)
        {
            state = (state + 1) % 4;//顺时针
        }
        else
        {
            state = (state + 4 - 1) % 4;//逆时针
        }
    }

    return (x == ex && y == ey);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    string str;
    while(cin >> ex >> ey)
    {
        cin >> n;
        int x = 0, y = 0, state = u;
        for(int i = 0; i < n; I++)
        {
            cin >> str;

            step[i].x = x, step[i].y = y, step[i].state = state;
            if(str == "Forward")
            {
                step[i].oper = f;
                x += cx[state];
                y += cy[state];
            }
            else if(str == "Right")
            {
                step[i].oper = r;
                state = (state + 1) % 4;//顺时针
            }
            else
            {
                step[i].oper = l;
                state = (state + 4 - 1) % 4;//逆时针
            }
        }

        for(int i = 0; i < n; I++)
        {
            if(step[i].oper != f && walk(step[i].x + cx[step[i].state], step[i].y + cy[step[i].state], i + 1, step[i].state))
            {
                cout << i + 1 << " Forward" << endl;
                break;
            }
            if(step[i].oper != l && walk(step[i].x, step[i].y, i + 1, (step[i].state + 4 - 1) % 4))
            {
                cout << i + 1 << " Left" << endl;
                break;
            }
            if(step[i].oper != r && walk(step[i].x, step[i].y, i + 1, (step[i].state + 1) % 4))
            {
                cout << i + 1 << " Right" << endl;
                break;
            }
        }
    }
}

G - Greeting Card

Kattis - greetingcard

题意:给出n个点的坐标,求在他们的连线中,有多少条的长度等于2018。
思路:先离线跑一遍三角形斜边恰好等于2018的情况,发现只有两种:a = 0, b = 2018 和 a = 1118, b = 1680 剩下的就是存下每个点,算出来他周围相距2018的点,若该点存在,cnt++
AC代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>

using namespace std;

//0 2018
//1118 1680

long long cx[] = {0, 0, 2018, -2018, 1118, 1680, -1118, -1680, 1680, 1118, -1118, -1680};
long long cy[] = {2018, -2018, 0, 0, 1680, 1118, 1680, 1118, -1118, -1680, -1680, -1118};

typedef pair<long, long> P;

const int maxn = 100000 + 5;

long long x[maxn], y[maxn];

int main()
{
    int n;
    scanf("%d", &n);
    set<P> st;
    P p;
    for(int i = 0; i < n; ++i) {
        scanf("%d %d", &x[i], &y[I]);
        p.first = x[I];
        p.second = y[I];
        st.insert(p);
    }
    long long sum = 0;
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < 12; ++j) {
            p.first = x[i] + cx[j];
            p.second = y[i] + cy[j];
            if(st.count(p)) {
                ++sum;
            }
        }
    }
    printf("%lld\n", sum / 2);
    return 0;
}

H - Imperfect GPS

Kattis - imperfectgps

I - Odd Gnome

Kattis - oddgnome
题意:签到题。给出一个序列,寻找King,King不会藏在序列首部或尾部,而且除了King,其他人的ID都是满足严格上升的。输出King的位置
思路:按照题意模拟即可。
AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;
const int maxn = 1005;
int a[maxn];

int main()
{
    int T, n;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &a[I]);
        }
        int flag = 0;
        for(int i = 2; i <= n; ++i) {
            if(a[i] == a[i-1]) {
                flag = I;
                break;
            }
            else if(a[i]<=a[i-1] && i >=3 && a[i]>a[i-2]) {
                flag = i-1;
                break;
            }
            else if(a[i]<=a[i-1] && a[i] <= a[i+1]) {
                flag = I;
                break;
            }
        }
        if(flag == 0) {
            printf("2\n");
        }
        else {
            printf("%d\n", flag);
        }
    }
    return 0;
}

J - Progressive Scramble

Kattis - progressivescramble
题意:给一个字符串,由空格和小写字母组成。先输入一个字母,‘e’表示加密,‘d’表示解密,后面跟的是待处理的字符串。
加密方式:前缀和%27
思路:简单模拟。这个水题发现的晚了,第三个小时才出
AC代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>

using namespace std;
string s;

int main()
{
   // freopen("in.txt", "r", stdin);
    int n, len, pre, now, ans;
    bool flag;
    char ch;
    cin >> n;
    getchar();
    while(n--) {
        ch = getchar();
        getchar();
        getline(cin, s);
        len = s.size();
        if(ch == 'e') {
            pre = s[0] == ' ' ? 0 : s[0] - 'a' + 1;
            for(int i = 1; i < len; ++i) {
                now = s[i] == ' ' ? 0 : s[i] - 'a' + 1;
                pre += now;
                //cout << pre << " ";
                ans = pre % 27;
                s[i] = ans == 0 ? ' ' : ans + 'a' - 1;
            }
            cout << s << endl;
        }
        else {
            pre = s[0] == ' ' ? 0 : s[0] - 'a' + 1;
            for(int i = 1; i < len; ++i) {
                now = s[i] == ' ' ? 0 : s[i] - 'a' + 1;
                for(int k = 0; ; ++k) {
                    now += 27 * k;
                    if(now >= pre) {
                        ans = (now - pre) % 27;
                        s[i] = ans == 0 ? ' ' : ans + 'a' - 1;
                        //cout << ans << endl;
                        pre += ans;
                        break;
                    }
                }
            }
            cout << s << endl;
        }
    }
    return 0;
}

K - Space Probe

Kattis - spaceprobe

L - Suspension Bridges

Kattis - suspensionbridges

M - Umbral Decoding

Kattis - umbraldecoding

相关文章

网友评论

    本文标题:2017 ICPC North American Qualifi

    本文链接:https://www.haomeiwen.com/subject/rzvbzftx.html