2017年浙江工业大学之江学院程序设计竞赛预赛

偶然看到这个比赛,为了找找感觉就参加了,做了几题后感觉自己好菜啊。。。

Problem A: L先生与晨跑

Time Limit:1 Sec  Memory Limit:128 MB
Submit:967  Solved:367
[Submit][Status][WebBoard]

Description

早起晨跑是一件痛苦的事情,好在可以代打(嘘,别让体育老师知道),为了决定谁去打卡,L先生和朋友Z打算玩一个游戏,L先生从抽屉里随机拿出K张扑克牌。

规则如下:每人至少拿一张,最多拿N张,谁先拿光扑克牌就明天就可以不用早起打卡,而另一个人就要下去打卡了。当然L先生和朋友Z都不是吃素的,各个心里打着小算盘,而友好的L先生决定让Z先拿。

Input

第一行包含一个正整数T,表示有T组测试数据(0<T<100000),每个测试包含一个正整数K1≤K≤55000)和一个正整数N1≤N≤2000),分别表示L拿出的扑克牌数和每人最多拿的牌数。 

Output

每组测试数据输出一行,如果L先生下去打卡则输出L,否则输出Z

Sample Input

2
5 5
6 5

Sample Output

L
Z


简单博弈题巴什博弈:有一堆n个珠子,每人轮流拿走若干个,轮到谁的回合拿不了珠子就算输。给出一个n,每次能拿走的珠子数量在区间[l,r]

n%(l+r)<l 则后手胜

#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
typedef long long ll;
const int maxn= 200005;
const int mod = 10007;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
int main()
{
    int k,n;
    rush()
    {
        scanf("%d%d",&n,&k);
        if(n%(1+k)<1)
            puts("Z");
        else puts("L");
    }
    return 0;
}


Problem B: The name of the people

Time Limit:1 Sec  Memory Limit:128 MB
Submit:885  Solved:331
[Submit][Status][WebBoard]

Description

In the Name of peopleisbound to be the hottest TV series these days. The anti-corruption storm hasaroused the audiences' great interests. And the classic emoticon(表情包)of Secretary LiDakang has been quite popular among theteenagers. Well, who is the popular king of this TV series? Please find out themost popular role according to the voting conditions.

Input

There are multiple cases.

The first line in each case contains the total voting numbern(0<n<1000). On the following n lines, there’s a namelength<15 representingthe role that a netizen votes for. The role’s name only consists of lowercaseand uppercase letters.

Output

For each case, outputs the role that is the most popular. (Weassures that the answer is unique.)

Sample Input

6
HouLiangpin
LiDakang
LiDakang
QiTongwei
LuYike
ChenHai

Sample Output

LiDakang

题意:输出出现名字次数最多的一个,用map处理即可

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
typedef long long ll;
const int maxn= 1005;
const int mod = 10007;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
map<string,int>mp;
char s[maxn][20];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        mp.clear();       //注意清空
        for(int i=0;i<n;i++)
        {
            scanf("%s",s[i]);
                mp[s[i]]++;
        }
        int ans=0;
        int maxi;
        for(int i=0;i<n;i++)
        {
            if(mp[s[i]]>ans)
            {
                ans=mp[s[i]];
                maxi=i;
            }
        }
        printf("%s\n",s[maxi]);
    }
    return 0;
}


Problem C: L先生与加密

Time Limit:1 Sec  Memory Limit:128 MB
Submit:463  Solved:294
[Submit][Status][WebBoard]

Description

L先生最近想给暗恋的同班女神Z写一封情书,但是需要经过同学ABCDEFG转交,为了保证情书内容不被公之于众(否则后果,你懂的),他决定采用高大上的维吉尼亚加密。
那么,问题来了,L先生的C语言是挂科的,所以代码写不出来,笔算内容又太多,感到很无助,你能帮助他吗? 

Input

多组测试例,处理到文件结束。(测试例数量<5

每行有两个字符串,之间用空格隔开,分别为明文a和密钥b。输入字符全都为小写。(字符串长度<=50

Output

每个加密结果占一行。输出字符全都小写。

Sample Input

datasecurity best

Sample Output

eelttiunsmlr

HINT


维吉尼亚密码引入了密钥的概念,即根据密钥来决定用哪一行的密表来进行替换,以此来对抗字频统计。假如对如下明文加密:


TO BE OR NOT TO BE THAT IS THE QUESTION

当选定RELATIONS作为密钥时,加密过程是:明文一个字母为T,第一个密钥字母为R,因此可以找到在R行中代替T的为K,依此类推,得出对应关系如下:

密钥:RELAT IONSR ELATI ONSRELATIO NSREL

明文:TOBEO RNOTT OBETH ATISTHEQUE STION

密文:KSMEH ZBBLK SMEMP OGAJXSEJCS FLZSY



简单模拟题,如果看不懂HINT看这里: 传送门

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
typedef long long ll;
const int maxn= 55;
const int mod = 10007;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
char s1[maxn],s2[maxn];
char ans[maxn];

int main()
{
    while(~scanf("%s",s1))
    {
        mst(ans,0);
        scanf("%s",s2);
        int len1=strlen(s1);
        int len2=strlen(s2);
        for(int i=0;i<len1;i++)
        {
            int k=(s1[i]+(s2[i%len2]-'a')-'a');
            k%=26;
            printf("%c",'a'+k);

        }
        printf("\n");
    }
    return 0;
}

Problem D:朋友Z与方程

Time Limit:1 Sec  Memory Limit:128 MB
Submit:953  Solved:210
[Submit][Status][WebBoard]

Description

在朋友Z的信中她问了L先生一道题目,可惜L先生太笨,你能帮助他解决吗?

已知等式:6*x^3 + 5*x^2+ 7*x + 9 == Y 给出Y的值请求出x( 0≤x≤10

Input

输入有多组测试数据,处理到文件结束(测试数据数量<=100000),每组测试数据给出一个浮点数Y(fabs(Y)<105)

Output

每行输出一个答案。

对于每个测试例如果存在满足条件的x,那么就输出x的值,并精确到小数点后4位,否则输出No solution!

Sample Input

100
-10

Sample Output

2.0877
No solution!

HINT

eps<=10-8

 

本来是很简单的二分题,但好像这里的评测系统时间卡得比较紧,在HDOJ上类似的题目能过这里却TLE

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
typedef long long ll;
const int maxn= 50000005;
const int mod = 10007;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
double y;

double F(double x)
{
    return 6*x*x*x+5*x*x+7*x+9-y;
}

int main()
{
    while(~scanf("%lf",&y))
    {
        if(F(0)>0||F(10)<0)
        {
            printf("No solution!\n");
            continue;
        }
        double l=0,r=10;
        for(int i=0;i<25;i++)    //这里的循环次数大约要在25~60的范围内
        {
            double m=(l+r)/2;
            if(F(m)>0)
                r=m;
            else l=m;
        }
        printf("%.4f\n",(l+r)/2);
    }
    return 0;
}


Problem E: L先生的回信

Time Limit:1 Sec  Memory Limit:128 MB
Submit:149  Solved:30
[Submit][Status][WebBoard]

Description

L先生打算回复来自朋友Z的上一封信,可是他担心信的内容在网络传送过程中出现错误,于是打算采用CRC校验方式保证信息完整性,可是他不知道应该怎么做,请你为他求出应该发送的比特序列。

Input

多组测试例,处理到文件结束。(测试例<5

每行有两个字符串,用空格隔开,分别为信的内容和生成多项式(长度<=50)。 
信的内容为二进制表示。 
生成多项式可能用x的多项式,也可能用二进制表示(格式见样例)

Output

每行输出一个加入CRC后发送的二进制序列,该序列不会长度超过32

Sample Input

110011 11001
11100011 x5+x4+x+1
10110 X4+X+1

Sample Output

1100111001
1110001111010
101101111

HINT


循环冗余校验码(CRC)的基本原理是:在K位信息码后再拼接R位的校验码,整个编码长度为N位,因此,这种编码也叫(NK)码。对于一个给定的(NK)码,可以证明存在一个最高次幂为N-K=R的多项式G(x)。根据G(x)可以生成K位信息的校验码,而G(x)叫做这个CRC码的生成多项式。校验码的具体生成过程为:假设要发送的信息用多项式C(X)表示,将C(x)左移R位(可表示成C(x)*2^R),这样C(x)的右边就会空出R位,这就是校验码的位置。用C(x)*2^R除以(2除法)生成多项式G(x)得到的余数就是校验码。


留坑。


Problem F: L先生的信与路由

Time Limit:1 Sec  Memory Limit:128 MB
Submit:370  Solved:101
[Submit][Status][WebBoard]

Description

L先生辛辛苦苦写完了要寄给朋友Z的信。

信将在网络中传输,已知网络由n个路由器互连而成,路由器之间的链路费用由邻接矩阵表示,L先生的PC机和服务器分别接在路由器s和路由器e上,忽略PC机和服务器到直接相连的路由器的费用,请求出L先生的PC机到服务器的最小费用。(路由网络可以看成有向图)。

Input

多组测试例,处理到文件结束。(测试例总量<5)。

每个测试例由若干行组成。 

第一行有三个数,分别是nse,之间用空格隔开。(0<n,s,e<200 
后续每行表示与每个路由器相连的路由器的编号和链路费用,用二元组(路由器编号链路费用(不超过10000))表示,二元组之间用空格隔开,每行表示一个路由器,行号按照路由器编号升序排列。

Output

每组测试例占一行,输出L先生的PC机到服务器的最小费用。

Sample Input

6 1 6
(2 2) (4 1) (3 5)
(1 2) (3 3) (4 2)
(1 5) (2 3) (4 3) (5 2) (6 2)
(1 1) (2 2) (3 3) (5 1)
(4 1) (3 2) (6 2)
(3 2) (5 2)

Sample Output

4


这道题其实是一个很裸的最短路题目,用vector(或邻接表)存边比较好,但我如何读入数据这里卡了很久,而且觉得我的读入方法还是好弱orz。。。

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <queue>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
typedef long long ll;
const int maxn= 205;
const int mod = 10007;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
vector<int>arr[maxn];
int mp[maxn][maxn];
int vis[maxn];
int dis[maxn];
char c1,c2;
char s[1000000];
int n,ss,tt;

void init()
{
    for(int i=0; i<=n; i++)
        arr[i].clear();
    for(int i=0; i<=n; i++)
        for(int j=0; j<=n; j++)
        {
            if(i==j)
                mp[i][j]=0;
            else mp[i][j]=INF;
        }
}

void spfa()
{
    mst(vis,0);
    mst(dis,0x3f);
    vis[ss]=1;
    dis[ss]=0;
    queue<int>q;
    q.push(ss);
    while(q.size())
    {
        int now=q.front();
        q.pop();
        vis[now]=0;
        for(int i=0; i<arr[now].size(); i++)
        {
            int v=arr[now][i];
            if(dis[v]>dis[now]+mp[now][v])
            {
                dis[v]=dis[now]+mp[now][v];
                if(vis[v]==0)
                {
                    q.push(v);
                    vis[v]=1;
                }
            }

        }
    }
    printf("%d\n",dis[tt]);
}
int main()
{
    int x,w;
    while(~scanf("%d%d%d",&n,&ss,&tt))
    {
        init();
        getchar();
        for(int i=1; i<=n; i++)
        {
            gets(s);
            int len=strlen(s);
            for(int j=0; j<len; j++)
            {
                if(s[j]=='(')
                {
                    x=0;
                    w=0;
                    j++;
                    while(s[j]!=' ')
                    {
                        x=x*10+s[j]-'0';
                        j++;
                    }
                    j++;
                    while(s[j]!=')')
                    {
                        w=w*10+s[j]-'0';
                        j++;
                    }
                    arr[i].push_back(x);
                    mp[i][x]=w;
                }
            }
        }
        spfa();
    }
    return 0;
}


Problem G: L先生的回信2

Time Limit:1 Sec  Memory Limit:128 MB
Submit:101  Solved:21
[Submit][Status][WebBoard]

Description

L先生的朋友Z收到了来自L先生的信,她发现可是信被L先生用RSA加密了,请你根据输入的两个质数和若干个用数字表示的需要用私钥解密的密文,来帮助她解密出公钥、私钥和明文。

一。 RSA公私钥生成
1.
随机选定两个大素数p, q.
2.
计算公钥和私钥的公共模数 n = pq .
3.
计算模数n的欧拉函数 φ(n) .
4.
选定一个正整数e,使1 < e < φ(n) ,eφ(n)互质.e取最小)
5.
计算d,满足 de ≡ 1  (mod φ(n) )d取最小)
6.n
e决定公钥, nd决定私钥.
二。加解密
该过程为LZ发消息,公钥为Z的公钥(n & e), 私钥为Z的私钥(n & d).
1.L
欲给Z发一个消息M,他先把M转换为一个大数m < n, 然后用Z的公钥(n & e)m加密为另一个大数
  c = m
e mod n
2.Z
收到L发来的大数c,着手解密.通过自己的私钥(n & d),得到原来的大数m: 
  m = c
d mod n
3.
再把m转换为M, Z即得到L的原始消息
这个过程之所以能通过,是因为有如下等式:
  c
d ≡(me)d ≡med (mod n)

Input

多组测试例,处理到文件结束。(测试例数量<20

输入每行有一个测试例,由若干个数字组成,前两个为质数(乘积不超过65535),后面每个为需用私钥解密的密文(长度<50),数和数之间用空格隔开。

Output

每个测试例的输出结果占一行,由若干个数字组成,分别为公钥e n、私钥d n和明文,数和数之间用空格隔开。

Sample Input

7 17 66 19
3 11 2 31 13 5 14

Sample Output

Public key: 5 119
Private key: 77 119
19 66
Public key: 3 33
Private key: 7 33
29 4 7 14 20

耐心看完后其实也不难。

我们可以一步步分析出结果,首先题目给出两个素数p1,p2,计算n=p1*p2 , 然后计算n的欧拉值,但我们不需要上欧拉函数的模板,因为m,n互质,x=φ(mn)=(m-1)(n-1)。e是与x互质最小的数,而(d*e)%x=1%x=1(d取尽量小),由此可以得到d的值,到现在,我们已经把Public keyPrivate key解了出来,接着就是明文,铭文中的数M与密文中的数N一一对应,对应关系为M=(N^d)%n,用一下快速幂取余即可。


#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
typedef long long ll;
const int maxn= 55;
const int mod = 10007;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
int p1,p2;
char c;
int a[maxn];

int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}

int fun(int a,int n,int c)
{
    int ans;
    a=a%c;
    if(n==0) ans=1%c;
    else
    {
        ans=fun(a*a,n/2,c)%c;
        if(n%2==1) ans=ans*a%c;
    }
    return ans;
}

int main()
{
    while(~scanf("%d%d",&p1,&p2))
    {
        int k=0;
        while(1)
        {
            int len=scanf("%d%c",&a[k++],&c);
            if(len!=2||c!=' ')
                break;
        }
        int n=p1*p2;
        int x=(p1-1)*(p2-1);
        int d,e;
        for(int i=2;i<x;i++)
        {
            if(gcd(x,i)==1)
            {
                e=i;
                break;
            }
        }
        for(int i=1; ;i++)
        {
            if((i*e)%x==1)
            {
                d=i;
                break;
            }
        }
        printf("Public key: %d %d\n",e,n);
        printf("Private key: %d %d\n",d,n);
        for(int i=0;i<k;i++)
        {
            int ans=fun(a[i],d,n);
            printf("%d",ans);
            if(i==k-1)
                printf("\n");
            else printf(" ");
        }
    }
    return 0;
}



Problem H: L先生运大米~

Time Limit:1 Sec  Memory Limit:128 MB
Submit:460  Solved:197
[Submit][Status][WebBoard]

Description

L先生接到了一个任务:使用一辆卡车来搬运大米,已知一辆卡车最多可以装N袋大米,每装一袋大米需要耗时5秒,而店里有M种大米,如果要求装的大米品种最多,如果品种数一样,则装的时间尽可能短,那么大米总价值的最大值是多少?

Input

输入有多组数据(数据组数<10000),第一行输入MN0<M,N<500),表示店里有M种大米,卡车最多能容纳N袋大米,接着输入M袋大米的价格PP<=65535)。 
NM0 0时,输入结束。

Output

大米总价值的最大值。

Sample Input

5 4
3 6 7 9 1
41 67
6334 26500 19169 15724 11478 29358 26962 24464 5705 28145 23281 16827 9961 491 2995 11942 4827 5436 32391 14604 3902 153 292 12382 17421 18716 19718 19895 5447 21726 14771 11538 1869 19912 25667 26299 17035 9894 28703 23811 31322
0 0

Sample Output

25
647067

 

水题。但总觉得题目描述有点难理解,我揣测出来的题意大概是:一辆卡车最多可以装n袋大米,而且车只能用一次,每装一袋大米需要耗时5分钟,店里有m种大米,每种大米有一个价值,问要装尽可能多的种类的大米(由于在满足这个条件下,同时要使装的时间尽可能短,那么每种大米最多装一袋),这时车上所有大米价值的最大值。于是问题就转化为这样:
(1).如果n>=m,那么就全部装上,结果即为所有大米的价值和。
(2).如果n<m,无法装上所有种类的大米,那么就装价值前n大的大米,结果这些大米的价值和。


#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <queue>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
typedef long long ll;
const int maxn= 505;
const int mod = 10007;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
int n,m;
int a[maxn];

bool cmp(const int &a,const int &b)
{
    return a>b;
}
int main()
{
    while(~scanf("%d%d",&n,&m)&&(n||m))
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        sort(a,a+n,cmp);
        int k=min(n,m);
        int ans=0;
        for(int i=0;i<k;i++)
        {
            ans+=a[i];
        }
        printf("%d\n",ans);
    }
    return 0;
}


接下来四题是同一类型的题目,都是求第n个素数,只是改变了数据范围和内存限制

其中前两题都可以用素数筛法实现,后面两题题可以用Meisell-Lehmer算法+二分搜索答案,我会单独写一个博客

Problem I: L先生与质数V1

Time Limit:1 Sec  Memory Limit:128 MB
Submit:1047  Solved:299
[Submit][Status][WebBoard]

Description

L先生想求出第n个质数(素数)是多少,你能帮助他吗?

Input

有多组测试例。(测试例数量<30)

每个测试例一行,输入一个数字n0<n<150000),输入0表示结束。

Output

输出测试例编号和第n个质数。

Case X: Y

Sample Input

1
2
3
4
10
100
0

Sample Output

Case 1: 2
Case 2: 3
Case 3: 5
Case 4: 7
Case 5: 29
Case 6: 541

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
typedef long long ll;
const int maxn= 2050005;           //只需要大约估算出maxn值
const int mod = 10007;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
int prime[maxn]= {0}; 
int num_prime=0;     
bool isprime[maxn]= {1,1}; 
void fun()
{
    for(int i=2;i<maxn;i++)
    {
        if(!isprime[i])
            prime[num_prime++]=i;
        for(int j=0;j<num_prime&&i*prime[j]<maxn;j++)
        {
            isprime[i*prime[j]]=1;
            if(i%prime[j]==0)
                break;
        }
    }
}
int main()
{
    fun();
    //printf("%d\n",num_prime);
    int n;
    int k=1;
    while(~scanf("%d",&n)&&n)
    {
        printf("Case %d: %d\n",k++,prime[n-1]);
    }
    return 0;
}


Problem J: L先生与质数V2

Time Limit:1 Sec  Memory Limit:128 MB
Submit:812  Solved:242
[Submit][Status][WebBoard]

Description

在解决了上一个质数问题之后,L先生脑洞大开,他还想计算下更多的质数,你能帮助他吗?

Input

有多组测试例。(测试例数量<=50000)
每个测试例一行,输入一个数字n0<n<=500000),输入0表示结束。

Output

输出测试例编号和第n个质数。

Case X: Y

Sample Input

1
2
3
4
10
100
0

Sample Output

Case 1: 2
Case 2: 3
Case 3: 5
Case 4: 7
Case 5: 29
Case 6: 541

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
typedef long long ll;
const int maxn= 7400005;         //只需要大约估算出maxn值
const int mod = 10007;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
int prime[maxn]= {0}; 
int num_prime=0;      
bool isprime[maxn]= {1,1}; 
void fun()
{
    for(int i=2;i<maxn;i++)
    {
        if(!isprime[i])
            prime[num_prime++]=i;
        for(int j=0;j<num_prime&&i*prime[j]<maxn;j++)
        {
            isprime[i*prime[j]]=1;
            if(i%prime[j]==0)
                break;
        }
    }
}
int main()
{
    fun();
    //printf("%d\n",num_prime);
    int n;
    int k=1;
    while(~scanf("%d",&n)&&n)
    {
        printf("Case %d: %d\n",k++,prime[n-1]);
    }
    return 0;
}

Problem K: L先生与质数V3

Time Limit:1 Sec  Memory Limit:128 MB
Submit:1146  Solved:124
[Submit][Status][WebBoard]

Description

在解决了上一个质数问题之后,L先生依然不甘心,他还想计算下更多范围内的质数,你能帮助他吗?

Input

有多组测试例。(测试例数量<70)
每个测试例一行,输入一个数字n0<n<=3000000),输入0表示结束。

Output

输出测试例编号和第N个质数。
Case X: Y

Sample Input

1
2
3
4
10
100
0

Sample Output

Case 1: 2
Case 2: 3
Case 3: 5
Case 4: 7
Case 5: 29
Case 6: 541



Meisell-Lehmer算法+二分搜索答案:传送门

Problem L: L先生与质数V4(应各位菊苣要求)

Time Limit:1 Sec  Memory Limit:16 MB
Submit:298  Solved:65
[Submit][Status][WebBoard]

Description

在解决了上一个质数问题之后,L先生依然不甘心,他还想计算下更多范围内的质数,你能帮助他吗?(没错这题题面和V3一毛一样)

Input

有多组测试例。(测试例数量<70)
每个测试例一行,输入一个数字n0<n<=3000000),输入0表示结束。

Output

输出测试例编号和第N个质数。
Case X: Y

Sample Input

1
2
3
4
10
100
0

Sample Output

Case 1: 2
Case 2: 3
Case 3: 5
Case 4: 7
Case 5: 29
Case 6: 541


Meisell-Lehmer算法+二分搜索答案:传送门

Problem M: L先生与数列

Time Limit:1 Sec  Memory Limit:128 MB
Submit:391  Solved:87
[Submit][Status][WebBoard]

Description

L先生又遇到了一道数学难题,你能帮助他吗。

在连续自然数数列列[a, b]之间选择n个不重复的数,要求它们的和为奇数,有多少种选法?

Input

多组测试数据,处理到文件结束。(测试数据数量<50
每行有一个测试例,分别是abn,且满足0<=b-a<=400<a,b,n<100

Output

对于每个测试例,输出一行代表其具有的组合个数。

Sample Input

11 19 2
11 19 3

Sample Output

20
40


由于数据范围较小,直接暴力做。先求出范围内奇数和偶数的个数,要使最后的和为奇数,那么选择的数中奇数的个数一定为奇数,那么我们只要枚举每个可能的奇数个数,然后就是从所有奇数和偶数中的取出一定个数即可(用数组实现组合数打表)
Attention:由于是组合数相乘,所以结果会比int的范围大,故用 long long

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <queue>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
typedef long long ll;
const int maxn= 45;
const int mod = 10007;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
ll C[maxn][maxn];
int a,b,n;

void init()
{
    f(i,0,maxn)
        C[i][0]=C[i][i]=1;
    f(i,2,maxn)
    f(j,1,i)
        C[i][j]=(C[i-1][j-1]+C[i-1][j]);
}

int main()
{
    init();
    //printf("%d\n",C[20][10]);
    while(~scanf("%d%d%d",&a,&b,&n))
    {
        int num1=0,num2=0;
        for(int i=a;i<=b;i++)
        {
            if(i&1)
                num1++;
            else num2++;
        }
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            if(i&1)
            {
                int k=n-i;
                ans+=(C[num1][i]*C[num2][k]);
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}


Problem N: L先生与阶乘

Time Limit:1 Sec  Memory Limit:128 MB
Submit:799  Solved:302
[Submit][Status][WebBoard]

Description

没错,可怜的L先生又遇到了一道数学难题!

n的阶乘的末尾有多少个0

Input

多测试例,处理到文件结束。(总测试例数量<15000

每行有一个测试例,为一个非负整数n(0<=n<15000)

Output

每个测试例对应的输出占一行

Sample Input

1
2
3

Sample Output

0
0
0

稍加分析可知,要在结果的末位形成一个零,必定是一个2和一个5相乘,那么我们只要将1~n的数分解质因数,统计这些数中2和5的个数,取小的那个数即可,易知2的个数一定比5的个数多,所以我们要计算的是5的个数。
由于直接暴力找5的个数会超时,我们可以模拟5进制数实现之

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<(b);++i)
typedef long long ll;
const int maxn= 55;
const int mod = 10007;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
int fun(int x)
{
    int sum=0;
    while(x)
    {
        sum+=x/5;
        x/=5;
    }
    return sum;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        printf("%d\n",fun(n));
    }
    return 0;
}


Problem O: Elastic Ball in the Frame

Time Limit:2 Sec  Memory Limit:128 MB
Submit:222  Solved:61
[Submit][Status][WebBoard]

Description

In a rectangular frame, there’s an elastic ball which can beregarded as a mass point(The ball can make elastic collisions with theframe).The frame lies on a smooth horizontal plane, and the initial position ofthe ball is at the lower left quarter(左下角)of the frame.Taking horizontal border as x axis and the vertical border as y axis, we canbuild the coordinate(坐标系). The position of theball is (0,0).Given the ball’s initial speed, you are supposed to find itsposition at time t. (The collision trace of the ball forms a mirrorreflection.)

Input

There is a positiveinteger n(n<1000) on the first line, representing the case number. Therefollows n lines, each line has 5 positive rational number,v(0<v<100), a(0<a<90), l(0<l<100),d(0<d<100),t(0<t<107),representing the ball’s initialspeed, the intersection angle between the ball’s initial speed and the x axis,the length of the vertical border, the length of the horizontal border, and thequeried time respectively.

Output

For each case, outputthe corresponding position in the (x,y) form, keeping two decimal places.

Sample Input

2
1 45 2 2 2
1 53.13 4 6 10

Sample Output

(1.41,1.41)
(6.00,0.00)

HINT

Sample 1 and sample 2 are shown below.

其实就是反射问题



   
   
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; #define mst(a,b) memset((a),(b),sizeof(a)) #define f(i,a,b) for(int i=(a);i<(b);++i) typedef long long ll; const int maxn= 55; const int mod = 10007; const ll INF = 0x3f3f3f3f; const double PI=acos(-1.0); const double eps = 1e-6; #define rush() int T;scanf("%d",&T);while(T--)
double v,a,l,d,t;
int main() {     rush()     {         scanf("%lf%lf%lf%lf%lf",&v,&a,&l,&d,&t);         double x=t*v*cos(a/180.0*PI);         double y=t*v*sin(a/180.0*PI);         double xx=int(x/d);         double yy=int(y/l);         double ansx=x-xx*d;         double ansy=y-yy*l;         if(xx!=int(xx/2.0)*2.0) ansx=d-ansx;         if(yy!=int(yy/2.0)*2.0) ansy=l-ansy;         printf("(%.2f,%.2f)\n",ansx,ansy);     }     return 0; }



Problem P: Mr.L and Cube

Time Limit:1 Sec  Memory Limit:128 MB  Special Judge
Submit:34  Solved:13
[Submit][Status][WebBoard]

Description

Mr.L travelsto a novel place, and it's not easy for him to choose the shortest path. Canyou help him?
Theplace is considered as an infinite three-dimensional space divided into grids.Some of them are black and the others are white. The black girds represent theland of the world and the white grids represent the air.

Obviously, Mr.L can only walk on the surface (including edge orvertex) of black grids. Luckily, the grids are regular. Every black grid sharescommon vertex with exact 8 other black grids and has no common edges or faceswith these black grids. The following picture shows a fraction of the gridworld:

 

 


Now, we place the center of one black grid on the origin and theedge of the grids are paralleled with axes. Also, we assume that every edge isexactly 1cm long. Carl has told you his starting point and the destinationpoint, help him to calculate the distance of the shortest path between them.

Input

There are multiple test cases. The first line of input is aninteger T indicating the number of test cases. For each test case:

The only line contains 6numbers X1, Y1, Z1, X2, Y2 and Z2 (-104 ≤ X1, Y1, Z1, X2, Y2, Z2 ≤104), representing the coordinates of the starting point and thedestination point. It is guaranteed that both points are on the surface ofblack grid.

Output

For each case, output the length in centimeters of the shortestpath from the starting point to the destination point. Absolute error orrelative error less than 10-8 will beaccepted.

Sample Input

3
0.5 0.5 0.5 0.5 -0.5 -0.5
-0.5 -0.5 -0.5 1.5 1.5 1.5
0.4 0.3 0.5 0.6 0.5 0.7

Sample Output

1.4142135623730950488016887242097
4.4721359549995793928183473374626
0.4472135954999579392818347337462

HINT


For the first sample, the starting point and the destinationpoint are on the same surface so just go straight there.

For the second sample, Carl can go to (0.5, 0.5, 0.5) first andthen go to the destination point.

For the third sample, Carl can also go to (0.5, 0.5, 0.5) firstand then go to the destination point.

 

留坑(据说这是WF级别的防AK题...)





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值