EOJ Monthly 2017.12 A+B+C

来源:互联网 发布:淘宝上正规药店是哪个 编辑:程序博客网 时间:2024/06/06 03:23
A. 唐纳德先生和假骰子

Time limit per test: 1.0 seconds

Memory limit: 256 megabytes

在进行某些桌游,例如 UNO 或者麻将的时候,常常会需要随机决定从谁开始。骰子是一种好方案。普通的骰子有六个面,分别是一点、二点、三点、四点、五点、六点,六面向上的概率相同。由于骰子只能产生六种情况,而实际桌游时,却常常有三到四人,所以,我们在掷骰子时,常常采用两颗骰子,这个「随机的选择」就由骰子向上点数之和直接决定。

我们采用这么一种方案,将向上点数之和对 p(人数)取模,模出来的 0,1,,p1 恰好对应 p 个人。但这并不一定是公平的。例如,如果你有算过的话,两枚普通的骰子,在四个人的情形下,就是不公平的。

所以唐纳德先生发明了一种假骰子,这种假骰子也有六个面,但六个面的点数就不再是 1,2,3,4,5,6,而是 a1,a2,a3,a4,a5,a6。如果他精心选择了这六个面的点数,他仍然可以强制公平。

先给出 p 和两枚假骰子六个面的点数,问是否公平。

Input

输入具有如下形式:

pa1 a2 a3 a4 a5 a6b1 b2 b3 b4 b5 b6

第一行一个整数 p (3p4)。

第二行六个整数,用空格隔开,表示第一枚骰子的点数 a1,a2,a3,a4,a5,a6 (1ai6)。

第三行六个整数,用空格隔开,表示第二枚骰子的点数 b1,b2,b3,b4,b5,b6 (1bi6)。

Output

如果公平输出 YES,否则输出 NO

Examples

input
41 2 3 4 5 61 2 3 4 5 6
output
NO
input
31 2 3 4 5 66 5 4 3 2 1
output

YES

直接暴力模拟

#include<iostream>#include<stdio.h>#include<string.h>#include<cmath>#include<algorithm>using namespace std;#define ll long long#define MOD 1000000007#define N 400010int map1[7];int map2[7];int map[37];int main(){    int n;    while(cin>>n)    {        memset(map,0,sizeof(map));        for(int i=1;i<=6;i++)            scanf("%d",&map1[i]);        for(int i=1;i<=6;i++)            scanf("%d",&map2[i]);        for(int i=1;i<=6;i++)        {            for(int j=1;j<=6;j++)            {                map[(map1[i]+map2[j])%n]++;            }        }        int flag=1;        for(int i=0;i<n;i++)        {            for(int j=i+1;j<n;j++)                if(map[i]!=map[j])                    flag=0;        }        if(flag==1)            cout<<"YES"<<endl;        else cout<<"NO"<<endl;    }    return 0;}

B. 在哈尔滨的寒风中

Time limit per test: 1.0 seconds

Memory limit: 256 megabytes

kblack 来到了寒冬中的哈尔滨,哈尔滨的寒风令 kblack 瑟瑟发抖。

世界上最远的距离,是你与宾馆只差一条冰街,而你却忘了穿上秋裤。

kblack 终于冲进了宾馆,宾馆大厅的地板铺满了五颜六色的地砖,可以被看作是一块 n×m 格的棋盘,为了能使冻僵了的双脚尽快暖和起来,kblack 决定在地砖上走动,但是他被速冻的双脚在棋盘地板上只能走马步。

kblack 居然想知道有多少对地砖(无序点对)他可以通过若干步马步互相抵达!

Input

输入包含一行两个正整数 nm,表示棋盘的大小,保证 1n×m109 。

Output

输出包含一个整数,表示 kblack 可以通过马步互相到达的无序地砖对数。

Examples

input
1 2
output
0
input
4 2
output
4
开始的思路是搜索,底层每个格子当做起点开始,因为是无序的,所以只向上搜索,到顶层结束,深度便是需要的对数,一直在中间测试部分超时

其实一看数据就知道是有规律的,就是没想出来。。。

今天看了解题报告才做恍然大悟状,超过3*4的棋盘,是可以两两到达的,根据题解思路写了份代码,算是间接 A了吧

#include<iostream>#include<stdio.h>#include<string.h>#include<cmath>#include<string>#include<algorithm>using namespace std;#define ll long long#define MOD 1000000007#define N 100010int dx[]={-2,-1,1,2};int dy[]={1,2,2,1};int n,m;ll gcd(ll a,ll b){    if(b==0)        return a;    return gcd(b,a%b);}int judge(int x,int y){    if(x<=n&&x>=1&&y>=1&&y<=m)        return 1;    return 0;}ll CC(int n,int m){    ll ans=1;    if(n<m)        return 0;        else if(n==m)            return 1;    int j=2;    ll temp=1;    int a=max(m,n-m);    int b=min(m,n-m);    for(int i=n;i>a;i--)    {        ans*=i;        if(j<=b||temp>1)        {            if (j<=b)            temp*=j;            if (temp>1)            {                ll GCD=gcd(ans,temp);                ans/=GCD;                temp/=GCD;            }        }        j++;    }    return ans;}int main(){    while(cin>>n>>m)    {        /*if(min(n,m)<2)        {            cout<<0<<endl;            continue;        }        ans=0;        for(int j=1;j<m;j++)        {            for(int i=1;i<=n;i++)            {                //cout<<"i  j "<<i<<" "<<j<<endl;                dfs(i,j,0);            }        }*/        if(min(n,m)==1)            cout<<0<<endl;            else if(max(n,m)==2)                cout<<0<<endl;        else if(n==3&&m==3)            cout<<CC(8,2)<<endl;        else if(m==2)            cout<<2*CC(n/2,2)+2*CC(n-n/2,2)<<endl;            else if(n==2)                cout<<2*CC(m/2,2)+2*CC(m-m/2,2)<<endl;        else if(m*n>=3*4)            cout<<CC(n*m,2)<<endl;    }

C. 易位构词

Time limit per test: 2.0 seconds

Memory limit: 256 megabytes

易位构词 (anagram),指将一个单词中的字母重新排列,原单词中的每个字母都出现有且仅有一次。例如 "unce" 可以被易位构词成 "ecnu"。在某些情况下,要求重排而成的依然是一个单词,但本题没有这种要求,因为我们根本没有词典。

我们所感兴趣的是,有些单词中的字母进行适当的重排后,可以使得构成的单词每个对应的位置上字母都不一样。例如 "unce" 和 "ecnu",就有 "u"  "e", "n"  "c", "c"  "n", "e"  "u"。现在给出一个单词,问是否存在这样一个重排。

Input

一行一个单词 s (1|s|105)。单词完全由 26 个小写英文字母构成。

Output

输出一个单词。如果有多解,输出任意解。如果不存在,输出 impossible

Examples

input
unce
output
ecnu
input
aaaaaa
output
impossible
显然最多的字母出现次数大于一半的情况是不行的。否则就将每个字母的位置和字母绑定一下,
按字母序对结构体进行排序。然后右移「出现最多的字母出现次数」位,再排回来就可以了
#include<iostream>#include<stdio.h>#include<string.h>#include<cmath>#include<string>#include<algorithm>using namespace std;#define ll long long#define MOD 1000000007#define N 100005int num[256];char s[N],temp[N];char ans[N];struct node{    char c;    int p;}map[N];bool cmp(node a,node b){    return num[a.c]>num[b.c]||(num[a.c]==num[b.c]&&a.c<b.c);}int main(){    scanf("%s",s);    int len=strlen(s);    int ma=0;    for(int i=0;i<len;i++)    {        map[i].c=s[i];        map[i].p=i;        num[s[i]]++;        if(num[s[i]]>ma)            ma=num[s[i]];    }    sort(map,map+len,cmp);    if((ma*2)>len)        cout<<"impossible"<<endl;    else    {        for(int i=0;i<len;i++)            temp[(i+ma)%len]=map[i].c;        for(int i=0;i<len;i++)            ans[map[i].p]=temp[i];        cout<<ans<<endl;    }    return 0;}
还一个字符串水题水过了easy的(暴力查找子串),hard一直超时,不发了



原创粉丝点击