吉首大学第八届“新星杯”大学生程序设计大赛(暨新生网络同步赛) |
问题 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;
}