Codeforces Round 313(div1)

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;
}
时间: 2024-08-08 21:58:03

Codeforces Round 313(div1)的相关文章

Codeforces Round #285 Div1 A and Div2 C

Problem 给一个图G,保证G是一个森林(坑!).图G含有N个点,给出每个点的两个属性:度数(degree).异或和(sum).度数表示该点与多少个点相连,异或和表示与其相连的点的编号的异或和(点编号从0开始,若度数为0则异或和为0).要求求出原图,输出边的个数和每条边两端的顶点. Limits Time Limit(ms): 1000 Memory Limit(MB): 256 N: [1, 2^16] degree: [0, N-1] Solution 由于G是森林,G的每一个连通图一定

Codeforces Round #290 Div1 A

Problem 给N串字符串Si,通常定义字典序大小关系为 'a'<'b'<'c'<......<'y'<'z',现要求重新定义大小关系使得对于任意 i,j(i<j)满足Si <Sj,输出大小关系(一串'a'-'z'的排列),或者输出不存在(任意大小关系都不能满足要求). Limits Time Limit(ms): 2000 Memory Limit(MB): 256 N: 100 |Si|: 100 Solution 用图论方法解决,发现满足拓扑关系.枚举相邻

Codeforces Round #290 Div1 B

Problem 有一只青蛙在x轴上跳,起初在原点,现有N种跳跃技能可以购买,每技能有两属性:跳跃长度Li 以及 花费Ci.若购买了第 i 种技能,则可以从 y 位置跳跃到 y+Li 或者 y-Li 位置,但需花费Ci 元.求最小花费使得青蛙可以跳到每一个整数点上,若无法做到,输出-1. Limits Time Limit(ms): 2000 Memory Limit(MB): 256 N: 300 Li: [1, 10^9] Ci: [1, 10^5] Solution 若购买了n个属性使得青蛙

Codeforces Round #313 (Div. 2) Gerald&#39;s Hexagon

给出一个六边形六条边的长度(六边形的每个角为120度),求出这个六边形中边长为1的等边三角形有多少个 由于每个角都是120度并且上下两条边是平行的,因此我们可以补出一个矩形,再减掉周边四个角的面积,用剩下面积除以每个小三角形的面积. #include<cstdio> using namespace std; double a,b,c,d,e,f; int main() { <span style="white-space:pre"> </span>s

Codeforces Round #313 (Div. 2) C Gerald&#39;s Hexagon 计数

// Codeforces Round #313 (Div. 2) C Gerald's Hexagon // 计数 // 关键是平行于a1的长度为1的有多少条,中间的这些*2,再加上a1 // 和a4,就是三角形的总和 // 还是挺简单的,注意递增的初始值,和变化,就ac了 #include <cstdio> #include <algorithm> #include <iostream> #include <cstring> using namespac

Codeforces Round #313 (Div. 1)

官方英文题解:http://codeforces.com/blog/entry/19237 Problem A: 题目大意: 给出内角和均为120°的六边形的六条边长(均为正整数),求最多能划分成多少个边长为1的正三角形. 题解: 把六边形补全变成一个正三角形,然后减去三个角的正三角形即可. Problem B: 题目大意: 给出长度相等的两个串AB,定义两个串相等 当且仅当  A=B  或者  当长度为偶数时,A[1...n/2]=B[1...n/2]  && A[n/2+1...n]=

[Codeforces Round #444 div1] C.DZY Loves Colors 【线段树】

题目链接:CF Round #444 div1 C 题目分析 这道题目是要实现区间赋值的操作,同时还要根据区间中原先的值修改区间上的属性权值. 如果直接使用普通的线段树区间赋值的方法,当一个节点表示的区间完全被要求修改的区间包含时,就直接打上赋值的标记然后 return .但是这样这个节点中每个位置原先的值不同,需要进行的属性权值修改也就不同,是不能直接实现的.如果我们在节点表示的区间被修改的区间包含时,并不直接打标记 return ,而是当节点表示的区间被修改的区间完全包含而且这个节点中的每个

【打CF,学算法——一星级】Codeforces Round #313 (Div. 2) A. Currency System in Geraldion

[CF简单介绍] 提交链接:http://codeforces.com/contest/560/problem/A 题面: A. Currency System in Geraldion time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output A magic island Geraldion, where Gerald lives,

Codeforces Round #313 (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/560 水笔场... A. Currency System in Geraldion time limit per test:2 seconds memory limit per test:256 megabytes A magic island Geraldion, where Gerald lives, has its own currency system. It uses banknotes of several va