1. 程式人生 > 實用技巧 >2020杭電多校#8(補)

2020杭電多校#8(補)

1003 Clockwise or Counterclockwise

題意

​ 判斷三個點按順序構成三角形,是順時針還是逆時針。

思路

​ 直接向量內積判讀即可。

程式碼

pair<ll, ll> a, b, c;

void slove() {
    cin >> a.first >> a.second >> b.first >> b.second >> c.first >> c.second;
    a.first = a.first - b.first; a.second = a.second - b.second;
    b.first = c.first - b.first; b.second = c.second - b.second;
    if(a.first * b.second - a.second * b.first > 0) puts("Clockwise");
    else puts("Counterclockwise");
}

1006 Fluctuation Limit

題意

​ 給一些區間,詢問是否可以構造一個數組,使每一個數字都在對應區間內,且相鄰兩個數字波動不超過\(k\)

思路

​ 從前向後做對所有區間做一次字首取min,然後反著對區間做一次後綴取min,最後的所有區間如果沒有\(L>R\)則輸出"YES",依次取區間左端點即可,反之輸出"NO"。

程式碼

int n, k;
pii a[maxn], res[maxn];

pii min(pii a, pii b) {
    a.first = max(a.first, b.first);
    a.second = min(a.second, b.second);
    return a;
}

void slove() {
    cin >> n >> k;
    for(int i = 0; i < n; i++) {
        scanf("%lld%lld", &a[i].first, &a[i].second);
        res[i].first = 0;
        res[i].second = mod;
    }
    res[0] = a[0];
    for(int i = 1; i < n; i++) {
        pii temp = res[i - 1];
        temp.first -= k; temp.second += k;
        res[i] = min(a[i], temp);
    }
    bool flag = true;
    for(int i = n - 2; i >= 0; i--) {
        pii temp = res[i + 1];
        temp.first -= k; temp.second += k;
        res[i] = min(res[i], temp);
        if(res[i].first > res[i].second) flag = false;
    }
    if(res[n - 1].first > res[n - 1].second) flag = false;
    if(!flag) puts("NO");
    else {
        puts("YES");
        for(int i = 0; i < n; i++) {
            printf("%lld", res[i].first);
            if(i == n - 1) puts("");
            else printf(" ");
        }
    }
}

1008 Hexagon

題意

​ 一個每個格子都是六邊形的二維座標。向六個方向行走依次是1,2,3,4,5,6。輸出從起點走完所有格子的方案,要求方案的轉向次數最多。

思路

​ 可以分成奇數和偶數分別模擬。

程式碼

void slove() {
    cin >> n;
    if(n % 2) {  //奇數
        cout << "16535424313262151";
        int cnt = 2;
        for(int i = 5; i <= n; i += 2) {
            cout << "616";
            for(int j = 0; j < cnt; j++) cout << "46";
            cout << "535";
            for(int j = 0; j < cnt; j++) cout << "35";
            cout << "424";
            for(int j = 0; j < cnt; j++) cout << "24";
            cout << "313";
            for(int j = 0; j < cnt; j++) cout << "13";
            cout << "262";
            for(int j = 0; j < cnt; j++) cout << "62";
            cout << "151";
            for(int j = 0; j < cnt; j++) cout << "51";
            cnt += 2;
        }
        cout << "6\n";
    }
    else {  //偶數
        cout << "64321";
        int cnt = 1;
        for(int i = 4; i <= n; i += 2) {
            cout << "616";
            for(int j = 0; j < cnt; j++) cout << "46";
            cout << "535";
            for(int j = 0; j < cnt; j++) cout << "35";
            cout << "424";
            for(int j = 0; j < cnt; j++) cout << "24";
            cout << "313";
            for(int j = 0; j < cnt; j++) cout << "13";
            cout << "262";
            for(int j = 0; j < cnt; j++) cout << "62";
            cout << "151";
            for(int j = 0; j < cnt; j++) cout << "51";
            cnt += 2;
        }
        cout << "6\n";
    }
}

1009 Isomorphic Strings

題意

​ 給一個字串,長度為n,如果存在\(n\)的因子\(k \quad (k!=n)\),使字串能分成\(n/k\)塊,且這些塊字串都屬於一個字串的迴圈同構串。

思路

​ 處理出\(n\)的所有因子,對於每一個因子,區分出\(n/k\)個子串,使用字串的最大最小表示法判斷是否為迴圈同構串。

程式碼

string minstr(string s) {
    int len = s.size(), i = 0, j = 1, k = 0;
    s += s;
    while(i < len && j < len && k < len - 1) {
        int temp = s[(i + k) % len] - s[(j + k) % len];
        if(!temp) k++;
        else {
            if(temp > 0) i = i + k + 1;
            else if(temp < 0) j = j + k + 1;
            if(i == j) j++;
            k = 0;
        }
    }
    if(i > j) swap(i, j);
    return s.substr(i, len);
}

void slove() {
    cin >> n >> s;
    string ans = "No";
    vector<int> fac;
    for(int i = 1; i * i <= n; i++) {
        if(n % i == 0) {
            fac.push_back(i);
            fac.push_back(n / i );
        }
    }
    for(int item: fac) {
        if(item == n) continue;
        string mins = minstr(s.substr(0, item));
        int k = n / item, pos = item, cnt = 0;
        for(int i = 1; i < k; i++) {
            string temps = minstr(s.substr(pos, item));
            if(mins == temps) cnt++;
        }
        if(cnt == k) ans = "Yes";
    }
    cout << ans << endl;
}