Codeforces Round #313 (Div. 2) A~E 题解B C E

A. Currency System in Geraldion

Problem Description:
A magic island Geraldion, where Gerald lives, has its own currency system. It uses banknotes of several values. But the problem is, the system is not perfect and sometimes it happens that Geraldionians cannot express a certain sum of money with any set of banknotes. Of course, they can use any number of banknotes of each value. Such sum is called unfortunate. Gerald wondered: what is the minimum unfortunate sum?

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<vector>
#include<map>
#include<set>
using namespace std;
int main()
{
    int n,i,a;
    while(~scanf("%d",&n))
    {
        int flag=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a);
            if(a==1) flag=1;
        }
        if(flag) printf("-1\n");
        else printf("1\n");
    }
}

B. Gerald is into Art

Problem Description:
Gerald bought two very rare paintings at the Sotheby’s auction and he now wants to hang them on the wall. For that he bought a special board to attach it to the wall and place the paintings on the board. The board has shape of an a1 × b1 rectangle, the paintings have shape of a a2 × b2 and a3 × b3 rectangles.

Since the paintings are painted in the style of abstract art, it does not matter exactly how they will be rotated, but still, one side of both the board, and each of the paintings must be parallel to the floor. The paintings can touch each other and the edges of the board, but can not overlap or go beyond the edge of the board. Gerald asks whether it is possible to place the paintings on the board, or is the board he bought not large enough?
题意:
给三个矩形的长和宽,问第一个矩形能否包住剩下的两个矩形
思路:
比较傻逼的做法,16个IF

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<vector>
#include<map>
#include<set>
using namespace std;
int main()
{
    int a1,a2,a3,b1,b2,b3;
    while(~scanf("%d%d",&a1,&b1))
    {
        scanf("%d%d%d%d",&a2,&b2,&a3,&b3);
        int flag=0;
        if(b1>=b2+b3&&a1>=a2&&a1>=a3||b1>=b2+a3&&a1>=a2&&a1>=b3) flag=1;
        else if(b1>=b2&&b1>=b3&&a1>=a2+a3||b1>=b2&&b1>=a3&&a1>=a2+b3) flag=1;
        else if(b1>=a2+b3&&a1>=b2&&a1>=a3||b1>=a2+a3&&a1>=b2&&a1>=b3) flag=1;
        else if(b1>=a2&&b1>=b3&&a1>=b2+a3||b1>=a2&&b1>=a3&&a1>=b2+b3) flag=1;
        else if(a1>=b2+b3&&b1>=a2&&b1>=a3||a1>=b2+a3&&b1>=a2&&b1>=b3) flag=1;
        else if(a1>=b2&&a1>=b3&&b1>=a2+a3||a1>=b2&&a1>=a3&&b1>=a2+b3) flag=1;
        else if(a1>=a2+b3&&b1>=b2&&b1>=a3||a1>=a2+a3&&b1>=b2&&b1>=b3) flag=1;
        else if(a1>=a2&&a1>=b3&&b1>=b2+a3||a1>=a2&&a1>=a3&&b1>=b2+b3) flag=1;
        if(flag) printf("YES\n");
        else printf("NO\n");
    }
}

C. Gerald’s Hexagon

Problem Description:
Gerald got a very curious hexagon for his birthday. The boy found out that all the angles of the hexagon are equal to . Then he measured the length of its sides, and found that each of them is equal to an integer number of centimeters. There the properties of the hexagon ended and Gerald decided to draw on it.

He painted a few lines, parallel to the sides of the hexagon. The lines split the hexagon into regular triangles with sides of 1 centimeter. Now Gerald wonders how many triangles he has got. But there were so many of them that Gerald lost the track of his counting. Help the boy count the triangles.
题意:
给一个六边形,每个角都是60度,顺时针给边,求里边有多少个边长为1的正三角形
思路:
把六边形补成一个大三角形,然后减去多出来的三个小三角形
我们补的和剩下的都必然是正三角形,因为六边形每个角都是60度
边长为x的正三角形包含x*x个边长为1的正三角形

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define lowbit(x) (x&(-x))
typedef long long LL;
const int maxn = 100005;
const int inf=(1<<28)-1;
LL fun(LL x)
{
    return x*x;
}
int main()
{
    int a1,a2,a3,a4,a5,a6;
    scanf("%d%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5,&a6);
    LL ans=0;
    ans+=fun(a1+a2+a6);
    ans-=fun(a2);
    ans-=fun(a6);
    ans-=fun(a4);
    printf("%lld\n",ans);
    return 0;
}

D. Equivalent Strings

Problem Description:
Today on a lecture about strings Gerald learned a new definition of string equivalency. Two strings a and b of equal length are called equivalent in one of the two cases:

They are equal.
If we split string a into two halves of the same size a1 and a2, and string b into two halves of the same size b1 and b2, then one of the following is correct:
a1 is equivalent to b1, and a2 is equivalent to b2
a1 is equivalent to b2, and a2 is equivalent to b1
As a home task, the teacher gave two strings to his students and asked to determine if they are equivalent.

Gerald has already completed this home task. Now it’s your turn!

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define maxn 200005
int cmp(char str1[],char str2[],int len)
{
    for(int i=0;i<len;i++)
    if(str1[i]!=str2[i]) return 0;
    return 1;
}
int judge(char str1[],char str2[],int len)
{

    if(cmp(str1,str2,len)) return 1;
    if(len%2) return 0;
    //printf("%s %s %d\n",str1,str2,len);
    if(judge(str1,str2,len/2)&&judge(str1+len/2,str2+len/2,len/2)) return 1;
    else if(judge(str1,str2+len/2,len/2)&&judge(str1+len/2,str2,len/2)) return 1;
    return 0;
}
int main()
{
    char str1[maxn],str2[maxn];
    while(~scanf("%s%s",str1,str2))
    {
        if(judge(str1,str2,strlen(str1))) printf("YES\n");
        else printf("NO\n");
    }
}

E. Gerald and Giant Chess

Problem Description:
Giant chess is quite common in Geraldion. We will not delve into the rules of the game, we’ll just say that the game takes place on an h × w field, and it is painted in two colors, but not like in chess. Almost all cells of the field are white and only some of them are black. Currently Gerald is finishing a game of giant chess against his friend Pollard. Gerald has almost won, and the only thing he needs to win is to bring the pawn from the upper left corner of the board, where it is now standing, to the lower right corner. Gerald is so confident of victory that he became interested, in how many ways can he win?

The pawn, which Gerald has got left can go in two ways: one cell down or one cell to the right. In addition, it can not go to the black cells, otherwise the Gerald still loses. There are no other pawns or pieces left on the field, so that, according to the rules of giant chess Gerald moves his pawn until the game is over, and Pollard is just watching this process.
题意:
给你一个h*w的格子,里边有n个不能走的格子,问你从1,1到h,w的方法数
思路:
ans=(1,1)~(h,w)不考虑格子的方法数-必经过格子的方法数
我们对这些不能走的点进行DP
dp[i]代表从(1,1)到点i不经过不能走的格子的方法数
dp[i]=(1,1)到i点不考虑不能走的格子数-sigma(在i左上方的点到i的不考虑不能走方法数)
ans=(1,1)~(h,w)的方法数-sigma(dp[i]*从i点到(h,w)不考虑不能走的格子的方法数)

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define lowbit(x) (x&(-x))
typedef long long LL;
const int maxn = 2005;
const int inf=(1<<28)-1;
const LL mod = 1e9+7;
pair<int,int>Par[maxn];
LL dp[maxn];
LL fac[1000010];
LL quick_pow(LL a,LL b)
{
    LL res=1,tmp=a;
    while(b)
    {
        if(b&1) res=(res*tmp)%mod;
        tmp=(tmp*tmp)%mod;
        b/=2;
    }
    return res;
}
LL C(LL n,LL m,LL mod)
{
    if(m>n|m<0) return 0;
    LL s1=fac[n],s2=fac[n-m]*fac[m]%mod;
    return s1*quick_pow(s2,mod-2)%mod;
}
void init()
{
    fac[0]=1;
    for(int i=1;i<1e6+10;++i)
    fac[i]=(fac[i-1]*i)%mod;
}
int main()
{
    init();
    int h,w,n;
    scanf("%d%d%d",&h,&w,&n);
    for(int i=1;i<=n;++i)
    scanf("%d%d",&Par[i].first,&Par[i].second);
    Par[++n]=make_pair(1,1);
    Par[++n]=make_pair(h,w);
    sort(Par+1,Par+n+1);
    //for(int i=1;i<=n;++i) printf("%d %d\n",Par[i].first,Par[i].second);
    dp[1]=1;
    for(int i=2;i<=n;++i)
    {
        int x=Par[i].first,y=Par[i].second;
        //printf("%d %d: ",x,y);
        dp[i]=C(x+y-2,x-1,mod);
        for(int j=2;j<i;++j)
        if(Par[j].first<=x&&Par[j].second<=y)
        {
            int fx=Par[j].first,fy=Par[j].second;
            //printf("%d--%d **",fx,fy);
            dp[i]-=dp[j]*C(x+y-fx-fy,x-fx,mod);
            dp[i]=(dp[i]%mod+mod)%mod;
        }
        //printf("%lld\n",dp[i]);
    }
    printf("%lld\n",dp[n]);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值