ICPC North Central NA Contest 2017

C题最后过的,ss条无限长直线将平面画成若干个区域,相邻的类型不一样(可知只需有两个类型就可染色完毕)。tt个询问,每次询问两个点所在区域是否是同一个类型。思考之后发现,ss条直线中使两个点在其同一侧的直线,并不对答案造成影响;故只需统计使两个点在两侧的直线的数量即可。
最后是否是相同的类型只需看上述直线的数量的奇偶性即可。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>

#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 4e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;

ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }

inline ll read() {
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

ll m_pow(ll x, ll n, ll m) {
    ll res = 1;
    while (n > 0) {
        if (n & 1)
            res = (res * x) % m;
        x = (x * x) % m;
        n >>= 1;
    }
    return res % m;
}

struct Point {
    double x, y;

    Point() {}

    Point(double _x, double _y) {
        x = _x;
        y = _y;
    }

    double operator^(const Point &b) const {
        return x * b.y - y * b.x;
    }
};

int s, t;
vector<Point> p1, p2;
double x1, y, x2, y2, x3, y3, x4, y4;

inline int check(Point v0, Point v1, Point v2) {
    double a = (v0 ^ v1);
    double b = (v0 ^ v2);
    return (a * b) < 0;
}

int main() {
    cin >> s;
    for (int i = 0; i < s; i++) {
        cin >> x1 >> y >> x2 >> y2;
        p1.push_back(Point(x1, y));
        p2.push_back(Point(x2, y2));
    }
    cin >> t;
    for (int i = 0; i < t; i++) {
        int sum = 0;
        cin >> x3 >> y3 >> x4 >> y4;
        for (int j = 0; j < s; j++) {
            Point v0 = Point(p2[j].x - p1[j].x, p2[j].y - p1[j].y);
            Point v1 = Point(x3 - p1[j].x, y3 - p1[j].y);
            Point v2 = Point(x4 - p1[j].x, y4 - p1[j].y);
            sum += check(v0, v1, v2);
        }
        if (sum & 1) printf("different\n");
        else printf("same\n");
    }
    return 0;
}

J题
裸最小生成树

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>

#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 4e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;

ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }

inline ll read() {
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

ll m_pow(ll x, ll n, ll m) {
    ll res = 1;
    while (n > 0) {
        if (n & 1)
            res = (res * x) % m;
        x = (x * x) % m;
        n >>= 1;
    }
    return res % m;
}

struct Edge {
    int fm, to, dist;

    bool operator<(const Edge &rhs) const {
        return dist < rhs.dist;
    }
};

vector<Edge> e;
int f[3000], n;

int find(int x) {
    if (f[x] != x) f[x] = find(f[x]);
    return f[x];
}

void merge(int x, int y) {
    int xx = find(x);
    int yy = find(y);
    f[xx] = yy;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++) {
            int tmp;
            scanf("%d", &tmp);
            if (i < j) e.push_back(Edge{i, j, tmp});
        }
    sort(e.begin(), e.end());
    for (int i = 1; i <= n; i++) f[i] = i;
    int rst = n;
    for (auto edge:e)
        if (rst > 1) {
            int x = edge.fm, y = edge.to;
            if (find(x) != find(y)) {
                merge(x, y);
                rst--;
                printf("%d %d\n", x, y);
            }
        }
    return 0;
}

I题
模拟。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>

#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 4e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;

ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }

inline ll read() {
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

ll m_pow(ll x, ll n, ll m) {
    ll res = 1;
    while (n > 0) {
        if (n & 1)
            res = (res * x) % m;
        x = (x * x) % m;
        n >>= 1;
    }
    return res % m;
}

int T;
string ap;
int a[127];
double d = acos(-1) / 7;

int main() {
    int T;
    scanf("%d\n", &T);
    while (T--) {
        double time = 0;
        getline(cin, ap);

        rep(i, 0, ap.size() - 1) {
            if (ap[i] == ' ') a[i] = 26;
            else if (ap[i] == '\'') a[i] = 27;
            else a[i] = ap[i] - 'A';
        }
        for (int i = 1; i < ap.size(); i++) {
            time += d * min(abs(a[i] - a[i - 1]), 28 - abs(a[i] - a[i - 1]));
        }
        printf("%.10lf\n", ap.size() + time);
    }
    return 0;
}

G题
dfs环的数量,基本功。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>

#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 4e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;

ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }

inline ll read() {
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

ll m_pow(ll x, ll n, ll m) {
    ll res = 1;
    while (n > 0) {
        if (n & 1)
            res = (res * x) % m;
        x = (x * x) % m;
        n >>= 1;
    }
    return res % m;
}

const int dx[] = {0, 0, 1, -1, 1, -1, 1, -1};
const int dy[] = {1, -1, 0, 0, -1, 1, 1, -1};
int m, n, mp[127][127] = {0}, vis[127][127] = {0}, cnt = 0;
string liner;

inline void dfs(int x, int y) {
    vis[x][y] = 1;
    rep(i, 0, 7) {
        int tx = x + dx[i];
        int ty = y + dy[i];
        if (tx > 0 && ty > 0 && tx <= m && ty <= n && mp[tx][ty] && !vis[tx][ty]) {
            vis[tx][ty] = 1;
            dfs(tx, ty);
        }
    }
}

int main() {
    cin >> m >> n;
    rep(i, 1, m) {
        cin >> liner;
        rep(j, 0, n - 1)if (liner[j] == '#') mp[i][j + 1] = 1;
    }
    rep(i, 1, m)rep(j, 1, n)if (mp[i][j] && !vis[i][j]) {
                ++cnt;
                dfs(i, j);
            }
    cout << cnt << endl;
    return 0;
}

H题
这题比较有意思,每次操作将序列最后的0变为1,然后这位之后全变为0,直到全为1为止。
二进制进位。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>

#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 4e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;

ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }

inline ll read() {
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

ll m_pow(ll x, ll n, ll m) {
    ll res = 1;
    while (n > 0) {
        if (n & 1)
            res = (res * x) % m;
        x = (x * x) % m;
        n >>= 1;
    }
    return res % m;
}

ll n, a[100];
char an;

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> an;
        if (an == 'Z') a[n - i] = 1;
        else a[n - i] = 0;
    }
    ll p = 1, sum = 0;
    for (int i = 0; i < n; i++) {
        sum += a[i] * p;
        p <<= 1;
    }
    cout << p - sum - 1 << endl;
    return 0;
}
posted @ 2020-02-29 23:47  Mr.doublerun  阅读(20)  评论(0)    收藏  举报