Test on 01/22/2017

1.字符游戏

  (moo.pas/c/cpp)

【问题描述】

小x和同学们喜欢玩一种游戏叫 "Moo".

他们总是站在一排,然后依次说出相应的一个字符,如果出错的同学,就要受到惩罚。

下面就是这个游戏的一个序列:

m o o m o o o m o o m o o o o m o o m o o o m o o m o o o o o

这个游戏的序列最初状态是 S(0) "m o o",也就是初始状态只有3个字符;如果要查询的字符超过3个,就要产生下一个字符序列,产生序列的规则如下:

s(k)是 s(k-1) +  "m o ... o"(k+2)个'o'  +s(k-1)

下面是相应的序列

S(0) = "m o o"

S(1) = "m o o m o o o m o o"

S(2) = "m o o m o o o m o o m o o o o m o o m o o o m o o"

注意:如果游戏的序列长度不够,就按照以上规则继续往下产生就可以了,所以游戏用的序列是无穷大的。

那么现在问题就出来了:

游戏中第x个人需要说的字符是什么呢?当然只有可能是 'm'或'o'.

本题有m(m<=10)个提问,每个提问给一个整数x,你要回答第x个人需要说出的字符数。

【输入】

第一行一个整数m(m<=10)

接下来m行,每行一个整数x (1 <=x <= 10^9)

【输出】

m行,每行一个字符,第i个人需要说的字符。

【输入输出样例1】

moo.in

moo.out

2

1

11

m

m

【数据范围】

  如题目描述。保证会有部分小数据查询位置在200以内。

辣鸡不会写QAQ

正解:递归,判断三部分。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int m,len[40],x;
char solve(int k,int i)
{
    if(k>len[i])    return solve(k,i+1);
    if(k<len[i-1])    return solve(k,i-1);
    if(k>len[i-1])    k-=len[i-1];
    if(k==1)    return 'm';
    if(k<i+3)    return 'o';
    k=k-i-3;    return solve(k,i-1);
}
int main(){
    cin>>m;
    len[0]=3;
    for(int i=1;i<=40;i++)
        len[i]=len[i-1]*2+i+3;
    for(int i=1;i<=m;i++)
    {    cin>>x;
        cout<<solve(x,0)<<endl;
    }
    return 0;
}
= =

1.暑假作业

  (mtime.pas/c/cpp)

【问题描述】

    暑假作业是必须要写的,越到假期结束前,写作业的效率就越高,小x就面临这个问题。

    现在小x有n个作业要完成。(1 <= N <= 1,000)并且每个作业有两个属性:Ti和Si.Ti表示第i项作业需要Ti的时间来完成,Si表示最迟必须Si时刻完成第i项作业。

    现在假设开始时刻为0,而小x想知道最晚什么时候开始写作业,可以把作业完成,这样他可以知道自己可以浮躁的时间。   

【输入】

第一行一个整数 N。

接下来N行,每行两个整数T_i (1 <= T_i <= 1,000)和 S_i(1 <= S_i <= 1,000,000)。

【输出】

一个整数,表示小x最晚开始写作业的时刻,如果根本完成不了,输出-1.

【输入输出样例】

mtime.in

mtime.out

4

3 5

8 14

5 20

1 16

2

小x最晚2时刻开始工作,在5时刻完成第一个作业,之后,在14时刻完成第2项作业,在15时刻完成第4项作业,之后在20时刻完成第3项作业。

【数据范围】

   30% n<=100

   50% n<=500

   100% 如 题目描述

应该以时间最后的优先啦,用布尔标记从时间最后找最佳完成时间,再向前标记。

由于时间最后为优先,所以只要确定最后完成时,前面就一定没有被标记。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,b=0,f[1000010];
struct qaq
{
    int t,s;
}a[1010];
bool mycmp(qaq x,qaq y)
{
    return (x.s>y.s);
}
int main()
{
    freopen("mtime.in","r",stdin);
    freopen("mtime.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i].t>>a[i].s;
    sort(a,a+n+1,mycmp);
    for(int i=1;i<=n;i++)
    {
        for(int j=a[i].s;j>=0;j--)
        {
            if(f[j]==0)    {b=j;    break;}
            if(j==0&&f[j]==1)    {cout<<-1<<endl;    return 0;}
        }
        for(int j=b;j>b-a[i].t;j--)
        {
            f[j]=1;
            if(j==0)    {cout<<-1<<endl;    return 0;}
        }
    }
    for(int i=1;i<=a[1].s;i++)
        if(f[i]==1)
        {    cout<<i-1<<endl;
            break;
        }
    return 0;
}
= =

1.福星

  (pathhead.pas/c/cpp)

【问题描述】

    小x的数学兼体育老师发明了一个很无聊的游戏。

    在体育课上,让小x和他的同学们一共N (1 <= N <= 100,000)个人,每个人抽取一个幸运号码A_i (1 <= A_i <= 1,000,000)。

    如果第i个人的幸运号码能被第j个人的幸运号码整除,那么第j个人就是第i个人的福星。自己当然不能是自己的福星。

    现在小x的数学兼体育老师想让小x算出,每个人都有多少个福星。

【输入】

第一行一个整数N。

接下来N行,每行一个整数A_i,表示每个人的幸运号码

【输出】

N行,每行一个整数,表示每个人的福星个数。

【输入输出样例】

pathhead.in

pathhead.out

5

2

1

2

3

4

2

0

2

1

3

【数据范围】

   一共有13组数据

       4组数据 n<=100  A_i<=200

       6组数据 n<=5000 A_i <=50000

       其余如题目描述

只会打暴力,没救了。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int n,a[100010],s[100010];
int main(){
    freopen("pathhead.in","r",stdin);
    freopen("pathhead.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(i!=j){
                if(a[i]==a[j])    s[i]++;
                if(a[i]>a[j]&&a[i]%a[j]==0)    s[i]++;
            }
    for(int i=1;i<=n;i++)
        cout<<s[i]<<endl;
    return 0;
}
= =

正解:筛法,找每个数有几个,然后往他们的倍数上加他们,他们的倍数一定整除以他们,有多少个他们,他们的倍数就有多少个福星。->好绕啊。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,maxx=0,a[1001000],ans[1001000],num[1001000];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
    {    cin>>a[i];
        num[a[i]]++;
        maxx=max(maxx,a[i]);
    }
    for(int i=1;i<=maxx;i++)
    {    if(num[i]>0)
        for(int j=i;j<=maxx;j+=i)
            ans[j]+=num[i];
    }
    for(int i=1;i<=n;i++)
        cout<<ans[a[i]]-1<<endl;
    return 0;
}
= =

骰子游戏 pogo

题目描述:

小x在玩一个骰子游戏。

这个骰子有6个面,如图所示:相对的两个面的值的累加和是7,数字1相对的面是数字6,2对着5,3对着4.

现在,有一个r行,c列的表格,骰子在表格最左上角,数字1朝上,数字3在1的右边。

现在小x按照以下规则进行移动:

1:他先把骰子从第一行的第一列,向右依次滚到最右边那列。

2:他把骰子向下滚到下一行。

3:他把骰子从右依次滚到最左边那列。

4:依次类推,他又把骰子滚到下一行,并按照第一步那样依次滚动

小x依次的重复以上步骤,直到把所有的格子都滚一遍。

在滚到每个格子的时候,小x都会记录朝上那面的格子的数字。

现在小x要考验一下你,所有数字的和是多少?

输入格式:

两个用空格隔开的整数r和c(1 ≤ r,c ≤ 100 000), 表示题目描述的表格的行和列。

输出格式:一个整数,如题目描述的所有朝上那面数字的累加和。

样例1:输入

样例2:输入

样例3:输入

3 2

3 4

737 296

样例1:输出

样例2:输出

样例3:输出

19

42

763532

50%数据保证 r和c小于等于100

纯模拟,模拟一下就ok,不过模拟要死。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
long long ans=0,m,n;
int main()
{
    freopen("pogo.in","r",stdin);
    freopen("pogo.out","w",stdout);
    cin>>n>>m;
    int t=m/4;
    for(int i=1;i<=n;i++)
        ans+=t*14;
    if(m%4==1)
    {    ans+=(n/4)*14;
        if(n%4==1)    ans+=1;
        if(n%4==2)    ans+=6;
        if(n%4==3)    ans+=12;
    }
    if(m%4==2)
    {    ans+=(n/6)*42;
        if(n%6==1)    ans+=5;
        if(n%6==2)    ans+=11;
        if(n%6==3)    ans+=19;
        if(n%6==4)    ans+=28;
        if(n%6==5)    ans+=36;
    }
    if(m%4==3)
    {    ans+=(n/2)*22;
        if(n%2==1)    ans+=11;
    }
    cout<<ans;
    return 0;
}
= =
No matter how you feel, get up , dress up , show up ,and never give up.
原文地址:https://www.cnblogs.com/Kaike/p/6340185.html