SPOJ TRNGL Make Triangle && CodeForces 550D Regular Bridge

Make Triangle

[介紹]

用(n-3)條對角線去切割凸n邊形,使之變爲三角形,詢問方案總數。~呵呵

[sol]

此題關鍵部分是枚舉圖形的哪一維才能確保不重複計數,其實題意上有強調,選取的對角線不能相交(在圖

形內部),想象一下圖形最後的狀態,每一條邊都在一個三角形內,每個邊都對應一個點,而這條邊對應不

同頂點的時候,走會出現對角線相交的情況,即從A、B兩點外的兩個點分別向A、B引直線,這些直線肯定

會相交,所以通過枚舉一條邊對應的不同頂點的方式避免重複的情況。。

枚舉1~n這條邊對應的不同頂點j(2<=j<=n - 1)

f[n] = ∑f[j] * f[n - i + 1]

[吐槽]

本來想通過枚舉新類型對角線的方式來搞(這樣不會重複),但是一條對角線把圖形分成兩部分的同時,子

圖形的對角線(對子圖形包含一點的對角線但是對於整體這個圖形卻包含了多點)混淆了類型……

另外f數組定義爲int類型的話。。1LL * f [i]*f[n - i + 1] (前面加一個1LL)

#include<cstdio>
#include<iostream>
using namespace std;
const int N = 1000 + 5;
const long long P = 100007;
int f[N];
int main()
{
    f[2] = 1;
    f[3] = 1;
    for(int i = 4; i <= 1000; i++)
    {
        long long  tmp = 0;
        for(int j = 2; j < i; j++)
            tmp = (tmp + 1LL * f[j] * f[i - j + 1]) % P;
        f[i] = tmp;
    }
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int k;
        scanf("%d", &k);
        printf("%d\n", f[k]);
    }
    return 0;
}

Regular Bridge

[sol]

首先要知道,對於無向圖來說,所有節點的度數之和一定爲偶數,或者說奇度點的個數爲偶數。這樣當k爲

偶數時,假設存在圖A滿足要求,把圖A的橋拆開,那麼分開的兩個子圖都只有一個奇度點,顯然與上面的

結論矛盾,因此k爲偶數時無解。

當k爲奇數時,我們先構造出橋的一點,編號爲1,連接2,3,4,…k點,另外的一個度在橋的另一邊,我們

另外再構造兩個點(k+1,k+2),這兩個點連接其餘的所有的點,2、3、4、、k再連接k-1個點就可以

#include<cstdio>
#include<iostream>
using namespace std;
const int N = 11000;
int num = 0, x[N], y[N];
void add(int s, int t)
{
    num++;
    x[num] = s;
    y[num] = t;
}
int main()
{
    int n;
    scanf("%d", &n);
    if (n % 2 ==0)
    {
        printf("NO");
        return 0;
    }
    if(n == 1)
    {
        printf("YES\n2 1\n1 2");
        return 0;
    }
    for(int i = 2; i <= n; i++)
        add(1, i);
    for(int i = 2; i <=n; i++)
        if (i % 2 == 0)
        {
            for(int j = i + 2; j <= n; j++)
                add(i, j);
        } else
        {
            for(int j = i + 1; j <= n; j++)
                add(i, j);
        }
    for(int i = 2; i <= n; i++)
    {
        add(n + 1, i);
        add(n + 2, i);
    }
    add(n + 1, n + 2);
    printf("YES\n");
    printf("%d %d\n", 2 * n + 4, 2 * num + 1);
    for(int i = 1; i <= num; i++)
    {
        printf("%d %d\n", x[i], y[i]);
        printf("%d %d\n", x[i] + n + 2, y[i] + n + 2);
    }
    printf("%d %d", 1, n + 3);
}
發佈了47 篇原創文章 · 獲贊 26 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章