吉首大学第八届“新星杯”题解AEGIJK

版权声明:本人大三在读,有错误烦请指正,共同进步- ( ゜- ゜)つロ 乾杯~点赞请按右上角,转载请标明出处: https://blog.csdn.net/hzyhfxt/article/details/85261147
  吉首大学第八届“新星杯”大学生程序设计大赛(暨新生网络同步赛)
问题 A: 组合数 组合数公式+分解质因子求因子个数
问题 E: Jack的A+B 细节
问题 G: 圆桌上的晚餐 循环遍历,dfs做法
问题 J: 老肖数等式
问题 I: 夫子云游 求方案数,dfs做法
问题 K: WaWa的难题 全排列后,找规律

 

什么叫不合理安排时间呢。。就是我这样了,疯狂卡题,可以过的题目的时间不够。。开题顺序很重要

问题 A: 组合数

时间限制: 1 Sec  内存限制: 128 MB
提交: 1715  解决: 105
[提交] [状态] [命题人:jsu_admin]

题目描述

求组合数C(N,M),以及C(N,M)因子个数。

输入

N和M,其中0<=M<=N<=50,以EOF结束。

输出

该组合数结果

样例输入 Copy

3 2
4 2

样例输出 Copy

3 2
6 4

思路:

(1)对数据运用公式预处理

(2)分解出整数的质因子,计算因子数

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <map>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int maxn = 1e6 + 5;
typedef long long ll;
ll K[55][55];
int prime[50];
int n,m,cnt;
ll sum;
int p[maxn];//记录数字的质因子
void init()
{
    for(int i=0;i<=51;++i)
        K[i][0]=1;
    for(int i=1;i<=51;++i)
        for(int j=1;j<=51;++j)
            K[i][j]=K[i-1][j]+K[i-1][j-1];
}
void primeFactor(ll n)//分解质因子的模板~~
{
    while(n % 2 == 0){
        p[2] ++;
        n /= 2;
    }
    for(int i = 3; i <= sqrt(n); i += 2){
        while(n % i == 0){
            p[i]++;
            n /= i;
        }
    }
    if(n > 2)
        p[n]++;
}
int main()
{
    init();
    while(scanf("%d%d",&n,&m) != EOF)
    {
        mem(p);
        cnt = 0;
        sum = 1;
        primeFactor(K[n][m]);
        for(int i = 1;i < maxn/2;i++)
            if(p[i] > 0)
                sum *= 1+p[i];
        cout<<K[n][m]<<" "<<sum<<endl;
        
    }
    return 0;
}

问题 E: Jack的A+B

时间限制: 1 Sec  内存限制: 128 MB
提交: 1882  解决: 546
[提交] [状态] [命题人:jsu_admin]

题目描述

现在有整数a,b,请按西方数字数量级方式输出a+b

输入

题目有多组测试数据
每组输入两个整数a,b
(0<=a,b<=10000000)

输出

输出西方数字数量级的a+b

样例输入 Copy

999 1
36 30
100000 100

样例输出 Copy

1,000
66
100,100

提示

输出的数从最低位起,每三位用逗号隔开

细节注意一下,特殊点判断一下~ 

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <map>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
int main()
{
    int a,b;
    while(scanf("%d%d",&a,&b) != EOF)
    {
        int x[15];
        int c = a+b,tmp=0;
        while(c)
        {
            x[tmp] = c % 10;
            c /= 10;
            tmp ++;
        }
        if(tmp == 4)
        {
            for(int i = 0;i < tmp;i++)
            {
                cout<<x[tmp-1-i];
                if(!i)  cout<<",";
            }
        }
        else{
            for(int i = 0;i < tmp;i++)
            {
                cout<<x[tmp-1-i];
                if( ((tmp-1-i) % 3 == 0) && (i != tmp - 1)) cout<<",";
            }
        }
        cout<<endl;
    }
    return 0;
}

问题 G: 圆桌上的晚餐

时间限制: 1 Sec  内存限制: 128 MB
提交: 1499  解决: 613
[提交] [状态] [命题人:jsu_admin]

题目描述

        大家一定在圆桌上吃过饭了,现在问题很简单,n个人坐在一个圆桌旁,其中有一些人是吃饱了的。那么当服务员端菜到某个人面前的时候,如果这个人吃饱了的话,那么这个人就会进行‘战术谦让’把菜端到下一个人的面前,如此反复直到这个菜遇到还没有吃饱的人的面前的时候,这个菜就会被吃掉。那么这个菜到底会被哪个人吃掉呢。

输入

 输入有多组数据 每组数据第一行有一个n,表示有n个人(1<= n <=1000)
 第二行有一个m表示菜会被端到第m个人面前(1<= m <= n)
 第三行有n个数字表示每个人的状态0表示还没有吃饱,1表示已经吃饱了
 (编号从1开始,第n个人下一个人是第一个人)

输出

    输出最终吃掉这个菜的人的编号答案一定存在

样例输入 Copy

5 
5
0 0 0 0 1
5 
3
1 0 1 1 1

样例输出 Copy

1
2

循环遍历一下每一个 人的状态就好了,沉迷dfs233


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <map>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int maxn = 1e3 + 5;
int a[maxn];
int eat;
int n,m;
void dfs(int x)
{
    if(a[x] == 0)
    {
        eat = x;
        return;
    }
    if(x+1>n)
        x = 0;
    dfs(x+1);
}
int main()
{
    while(scanf("%d",&n) != EOF)
    {
        mem(a);
        scanf("%d",&m);
        for(int i = 1;i <= n;i ++)  scanf("%d",&a[i]);
        dfs(m);
        cout<<eat<<endl;
    }
    return 0;
}

问题 J: 老肖数等式

时间限制: 1 Sec  内存限制: 128 MB
提交: 1534  解决: 704
[提交] [状态] [命题人:jsu_admin]

题目描述

老肖前几年当了小学数学老师,他每天都会布置一次题目,他布置题目有个习惯,他只布置两个数的加法,两个数都不超过100,而且会让所有的题目答案都是一样的,所以这真的是一个奇怪的数学老师呢,他又有点想偷点懒,想你帮他做个自动出试卷的程序,你能帮他解决这个问题吗?

输入

多组输入,每行输入一个数x作为等式答案(0<=x<=200)

输出

每行输出一个等式,等式里的两个数a,b(0<=a,b<=100)

样例输入 Copy

5
3

样例输出 Copy

1. 0+5=
2. 1+4=
3. 2+3=
1. 0+3=
2. 1+2=

水题不解释~

#include <stdio.h>
int main()
{
    int x;
    while(scanf("%d",&x) != EOF)
    {
        int t = 0;
        for(int i=0,j=x;i<=x/2&&j>=0;i++,j--)
        {
            t++;
            printf("%d. %d+%d=\n",t,i,j);
        }
    }
    return 0;
}

问题 I: 夫子云游

时间限制: 1 Sec  内存限制: 128 MB
提交: 262  解决: 176
[提交] [状态] [命题人:jsu_admin]

题目描述

改编自猫腻所著的同名小说《将夜》目前正在火热开播,其中男主角宁缺在考书院二层楼时遇一题“那年春,夫子出国游历,遇桃山美酒,遂寻径登山赏桃品酒,一路摘花饮酒而行,始斩一斤桃花,饮一壶酒,后夫子惜酒,故再斩一斤桃花,只饮半壶酒,再斩一斤桃花,饮半半壶酒,如是而行……至山顶,夫子囊中酒尽,惘然四顾,问:夫子一共斩了几斤桃花,饮了几壶酒?”而当我们的男主角宁缺看到这道题目时,更是直接来了句“谁出的这道题,太二了”,紧接着就提笔写下了“夫子饮二壶酒,斩尽满山桃花”后直接就交卷走人了赢得书院弟子的大赞。

今夫子再次游历,他提着酒壶,从出院出来,酒壶中有酒2斗,他边走边唱:

    无事街上走,提壶去打酒。
    逢店加一倍,遇花喝一斗。

这一路上,他一共遇到店M(0<M<=10)次,遇到花N(0<M<=10)次,已知最后一次遇到的是花,他正好把酒喝光了。

请计算夫子遇到店和花的合理的次序种数。

可以把遇店记为a,遇花记为b,如果M=5,N=10。则:babaabbabbabbbb 就是合理的次序之一。

输入

M、N 分别为遇到店和花的次数

输出

所有可能店和花次序方案的个数

样例输入 Copy

5 10

样例输出 Copy

14

排列求方案数,dfs大法好

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <map>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
int cnt;
void dfs(int a,int b,int c)//a:店 b:花 c:酒
{
    if(c==1 && b==1 && a==0)//满足条件“最后一次遇到的是花,他正好把酒喝光了”,找到了
    {
        cnt++;
        return;
    }
    if(a>0)
        dfs(a-1,b,c*2);
    if(b>0)
        dfs(a,b-1,c-1);
}
int main()
{
    int n,m;
    while(scanf("%d%d",&m,&n) != EOF)
    {
        cnt = 0;
        dfs(m,n,2);
        cout<<cnt<<endl;
    }
    return 0;
}

问题 K: WaWa的难题

时间限制: 1 Sec  内存限制: 128 MB
提交: 474  解决: 89
[提交] [状态] [命题人:jsu_admin]

题目描述

HaHa和WaWa是好朋友,他们在临近期末的这段时间一起宅在图书馆学习。
今天HaHa在书上看到一个排列组合题目,思考很久后,仍然找不出其中的规律。
于是他把题目叙述给了WaWa。
题目:
————————————————————————
一个长度为N的排列,由数字1~N组成,它满足两个条件。
1、数字1永远在第一位。
2、任意两个相邻数字之差小于等于2。
现在给出一个N,
你能知道能组成多少个符合条件的排列吗?。
例如:
N=4
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
所以答案为4
————————————————————————
WaWa听后也是一脸懵逼。
现在WaWa想求助于你们,WaWa给出一个正整数N,问你用1~N能组成多少个符合题意的排列。

输入

多组数据。
每组数据输入一个正整数N(1<=N<=100)。

输出

输出符合题意的排列个数

样例输入 Copy

2
4

样例输出 Copy

1
4

 找规律题,全排列打表数一下(我的同学们直接打表搜索,我好蠢数的眼睛都花了。。。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <map>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
ll a[110] = {1};
int n;
void init()
{
    a[2] = 1;
    a[3] = 2;
    a[4] = 4;
    a[5] = 6;
    for(int i = 6;i <= 110;i++)
    {
        a[i] = a[i-3] + a[i-1] + 1;
    }
}
int main()
{
    init();
    while(scanf("%d",&n) != EOF)
    {
        if(n == 1)//1的时候特判一下
            cout<<1<<endl;
        else
            cout<<a[n]<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hzyhfxt/article/details/85261147