1. 程式人生 > >Codeforces Round 313(div1)

Codeforces Round 313(div1)

補全 print 依據 ng- 部分 代碼 cst force else


A題:

題目大意:

給出內角全為120度的六邊形的六條邊的邊長,求由多少邊長為1的等邊三角形構成。


解題思路:

將六邊形補全為一個大的等邊三角形,則大的等邊三角形的邊長為六邊形的相鄰三邊之和,接著減去補的部分。

補的部分是三個邊長為認識3個不相鄰的六邊形邊長的長度構成的等邊三角形,邊長為a的等邊三角形,由a*a個邊

長為1的小三角形構成。


代碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int main()
{
    int a[10];
    for(int i=0;i<6;i++)
    {
        scanf("%d",&a[i]);
    }
    long long cur=a[0]+a[1]+a[2];
    long long ans=cur*cur-a[0]*a[0]-a[2]*a[2]-a[4]*a[4];
    cout<<ans<<endl;
    return 0;
}

B. Equivalent Strings


題目大意:

依據給定的規則推斷字符串相等。


解題思路:

依照題意遞歸寫就可。


代碼:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=200000+1000;
char s1[maxn];
char s2[maxn];
int judge(int st1,int en1,int st2,int en2)
{
    int sign=0;
    for(int i=st1,j=st2;i<=en1;i++,j++)
    {
        if(s1[i]!=s2[j])
        {
            sign=1;
            break;
        }
    }
    if(sign==0)
    return 1;
    else
    {
        if((en1-st1+1)%2==0)
        {
            int mid1=st1+(en1-st1+1)/2-1;
            int mid2=st2+(en2-st2+1)/2-1;
            if(judge(st1,mid1,st2,mid2)&&judge(mid1+1,en1,mid2+1,en2))
            return 1;
            if(judge(st1,mid1,mid2+1,en2)&&judge(mid1+1,en1,st2,mid2))
            return 1;
        }
    }
    return 0;
}
int main()
{
    int len1,len2;
    scanf("%s%s",s1,s2);
    len1=strlen(s1);
    len2=strlen(s2);
    if(len1!=len2)
    cout<<"NO\n"<<endl;
    else
    {
        int sign;
       sign=judge(0,len1-1,0,len1-1);
       if(sign)
       printf("YES\n");
       else
       printf("NO\n");
    }
    return 0;
}


C. Gerald and Giant Chess


題目大意:

給定h*w的格子,n個不可走的點。從(1,1)到(h,w)點。每次僅僅能向下或者向右。求有多少種走法?


解題思路:

首先先不考慮不可走的點,有C(h+w-2,h-1)種走法,一共走h+w-2步,向下的有h-1步。

接著考慮當中的不可走的

點,對於一個不可走的點(x,y)。它走到這個的點的走法是dp[i],它少走的是dp[i]*C(h-x,w-y,h-x),於是把每一個不可走

的點當為終點。能夠求出全部的走法數。


代碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int h,w,n;
const int maxn=200000+100;
const int mod=1000000000+7;
long long c[maxn];
long long inv[maxn];
long long dp[5000];
struct node
{
    int x;
    int y;
}a[10000];
long long pow_mod(long long a,int b)//矩陣高速冪
{
    long long ans=1;
    while(b)
    {
        if(b&1)
        ans=(ans*a)%mod;
        a=(a*a)%mod;
        b=b/2;
    }
    return ans;
}
long long com(int x,int y)//求組合數C(x,y)
{
    return ((c[x]*inv[y])%mod*inv[x-y])%mod;
}
bool cmp(node u,node v)
{
    if(u.x==v.x)
    return u.y<v.y;
    return u.x<v.x;
}
int main()
{
    scanf("%d%d%d",&h,&w,&n);
    for(int i=0;i<n;i++)
    scanf("%d%d",&a[i].x,&a[i].y);
    sort(a,a+n,cmp);
    long long ans=0;
    c[0]=1;
    for(int i=1;i<maxn;i++)
    c[i]=c[i-1]*i%mod;
    inv[0]=1;
    for(int i=1;i<maxn;i++)
    inv[i]=pow_mod(c[i],mod-2);//費馬小定理求逆。a^(p-2)=a^(-1)
    ans=com(h+w-2,h-1);
    for(int i=0;i<n;i++)
    {
        dp[i]=com(a[i].x+a[i].y-2,a[i].x-1);
        for(int j=0;j<i;j++)//求過第i個點的方法數
        {
            if(a[j].x<=a[i].x&&a[j].y<=a[i].y)//推斷能否夠到達i點
            {
                dp[i]-=(dp[j]*com(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x))%mod;
                dp[i]=(dp[i]+mod)%mod;
            }
        }
        ans=(ans-(dp[i]*com(h+w-a[i].x-a[i].y,h-a[i].x))%mod+mod)%mod;
    }
    cout<<ans<<endl;
    return 0;
}




Codeforces Round 313(div1)