1. 程式人生 > >Codeforces Round #313 (Div. 2) 解題報告

Codeforces Round #313 (Div. 2) 解題報告

post play 一個 content tex == 分割 公式 overflow

A. Currency System in Geraldion:

  • 題意:有n中不同面額的紙幣,問用這些紙幣所不能加和到的值的最小值。
  • 思路:顯然假設這些紙幣的最小錢為1的話,它就能夠組成隨意面額。

    假設這些紙幣的最小值大於1,那麽它所不能組成的最小面額就是1.所以自學求最小值就可以。

  • 我的代碼:
#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long int LL; const int M = 100009,INF = 0x3fffffff; int main(void) { //problem: , address: int n, x, y = INF; cin >> n; while (n--) { cin >> x; if
(x < y) swap(x, y); } if(y <= 1) cout << "-1" << endl; else cout << "1" << endl; return 0; }

B. Gerald is into Art:

  • 題意:給定三個矩形的 長和款。第一個矩形作為容器。最後兩個矩形不可重疊且水平的放置在當中,問能否放下?
  • 思路:這裏第一步先把第二個矩形放入容器的左下角顯然是最好的策略,能夠給第三個矩形最大的可能空間(比賽的時候不夠細致,沒有註意,第一個大矩形反正左下角必須滿足能放下的條件,就沒過大數據),註意這裏第一個矩形有橫放和豎放兩種情況。第二步再把第三個矩形放入剩余空間,這時候放置有兩種情況:技術分享
    ,每種放置情況第三個矩形又分為橫放和豎放兩種類型。這樣就把放置問題分為了8種情況,滿足隨意情況就可以。

  • 我的代碼:
#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int M = 100009,INF = 0x3fffffff;


int main(void) {
    int a1, a2, a3, b1, b2, b3;
    cin >> a1 >> b1 >> a2 >> b2 >> a3 >> b3;
    int x = a1 - a2, y = b1 - b2;
    bool ans = false;
    if ( (b2 <= b1 && x >= a3 && b3 <= b1) || (x >= 0 && a3 <= a1 && b3 <= y) || (y >= 0 && x >= b3 && a3 <= b1) || (x >= 0 && b3 <= a1 && a3 <= y) ) ans =true;
    x = a1 - b2;
    y = b1 - a2;
    if ( (y >= 0 && x >= a3 && b3 <= b1) || (x >= 0 && a3 <= a1 && b3 <= y) || (y >= 0 && x >= b3 && a3 <= b1) || (x >= 0 && b3 <= a1 && a3 <= y) ) ans =true;
    if (ans) cout << "YES" << endl;
    else cout << "NO" << endl;
    return 0;
}

C. Gerald’s Hexagon:

  • 題意:用等邊三角形堆積成一個六邊形,六邊形每個內角的為120度。告訴你這個六邊形的六條邊的長度,問該六邊形是由多少個等邊三角形組成的。
  • 思路:求出這和整個六邊形的面積。再除以三角形的面積,就能夠了。

    技術分享依據內角都為120度的特點,總是能把六邊形切為如圖的四個三角形。邊上三個三角形面積easy計算。那麽依據余弦公式:c2=a2+b2?2abcosθ能夠求出內部三角形的邊長。

    再依據海倫公式:p=(a+b+c)/2 s=p(p?a)(p?b)(p?c)?????????????????就可以算出內部三角形面積。

  • 我的代碼:
#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int M = 100009,INF = 0x3fffffff;
double pi = sqrt(3), eps = 1e-3;

int main(void) {
    double sum = 0, a, b, c, d, e, f;
    cin >> a >> b >> c >> d >> e >> f;
    double x = sqrt((a * a) + (b * b) + a * b);
    double y = sqrt((c * c) + (d * d) + c * d);
    double z = sqrt((e * e) + (f * f) + e * f);
    double s = (x + y + z) / 2;
    //cout << x << " " << y << " "<< z << endl;
    sum += sqrt(s * (s - x) * (s - y) * (s - z));
    //cout << sum << endl;
    sum += 0.25 * pi * (a * b + c * d + e * f);
    cout << int(sum / ( pi / 4) + eps) << endl;
    return 0;
}

D. Equivalent Strings

  • 題意:給定兩個字符串同性的法則。推斷其是否同性。
  • 遞歸就可以。但是比賽的代碼在大數據的時候超時了。後來加了一個剪枝過了。

    然後超時的主要原因是用了string後,會出現多次復制字符串的情況,把string換為char*,時間縮短10倍!

  • string實現的代碼:
#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int M = 100009,INF = 0x3fffffff;

bool same(string a, string b) {
    int A[26], B[26];
    memset(A, 0, sizeof(A));
    memset(B, 0, sizeof(B));
    for (int i = 0; i < a.size(); i++) {
        A[a[i] - ‘a‘]++;
        B[b[i] - ‘a‘]++;
    }
    for (int i = 0; i < 26; i++) {
        if (A[i] != B[i]) return false;
    }
    if (a == b) return true;
    if (a.size() % 2 != 0) return false;
    string x1, x2, y1, y2;
    for (int i = 0; i < a.size() / 2; i++) {
        x1 += a[i];
        x2 += b[i];
        y1 += a[i + a.size() / 2];
        y2 += b[i + a.size() / 2];
    }
    return (same(x1, x2) && same(y1, y2)) || (same(x1, y2) && same(y1, x2));
}

int main(void) {
    ios::sync_with_stdio(false);
    string a, b;
    while (cin >> a >> b) {
        if (same(a, b)) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}
  • char* 實現的代碼:
#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int M = 100009,INF = 0x3fffffff;

bool str (char a[], char b[], int n) {
    bool ans = true;
    for (int i = 0; i < n; i++) {
        if (a[i] != b[i]) {
            ans = false;
            break;
        }
    }
    return !ans;
}

bool same(char a[], char b[], int n) {
    int A[26], B[26];
    memset(A, 0, sizeof(A));
    memset(B, 0, sizeof(B));
    for (int i = 0; i < n; i++) {
        A[a[i] - ‘a‘]++;
        B[b[i] - ‘a‘]++;
    }
    for (int i = 0; i < 26; i++) if (A[i] != B[i]) return false;
    if (!str(a, b, n)) return true;
    if (n % 2 != 0) return false;
    return (same(a, b + n / 2, n / 2) && same(a + n / 2, b, n / 2)) || (same(a, b, n / 2) && same(a + n / 2, b + n / 2, n / 2));
}

int main(void) {
    ios::sync_with_stdio(false);
    char a[200009], b[200009];
    while (cin >> a >> b) {
        int n = strlen(a);
        if (same(a, b, n)) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}

Codeforces Round #313 (Div. 2) 解題報告