可恶,要开学了,好烦,来点题目压压惊吧
题目背景
本题为提交答案题,您可以写程序或手算在本机上算出答案后,直接提交答案文本,也可提交答案生成程序。
题目描述
将 1, 2, \ldots , 91,2,…,9 共 99 个数分成 33 组,分别组成 33 个三位数,且使这 33 个三位数构成 1 : 2 : 31:2:3 的比例,试求出所有满足条件的 33 个三位数。
输入格式
无
输出格式
若干行,每行 33 个数字。按照每行第 11 个数字升序排列。
输入输出样例
输入 #1复制
无
输出 #1复制
192 384 576 * * * ... * * * (剩余部分不予展示)
这题目,理解倒是,好理解,当然代码也不难,一看到,每个数字用一次,满足特定的条件输出脑袋就闪过了,dfs
全排序一次,满足的就输出,纯纯的暴力,这题目要的是答案过程,时间无伤大雅
#include<stdio.h>
int map[15];
int ans[10];
int i=1;
void dfs(int l){
if(l==10){
if(2*(ans[1]*100+ans[2]*10+ans[3])==ans[4]*100+ans[5]*10+ans[6]&&3*(ans[1]*100+ans[2]*10+ans[3])==ans[7]*100+ans[8]*10+ans[9]){
printf("%d%d%d %d%d%d %d%d%d\n",ans[1],ans[2],ans[3],ans[4],ans[5],ans[6],ans[7],ans[8],ans[9]);
}
}
else{
for(int y=1;y<=9;y++){
if(map[y]==0){
ans[i]=y;
map[y]=1;
i++;
dfs(i);
map[y]=0;
i--;
}
}
}
}
int main(){
printf("192 384 576\n");
printf("219 438 657\n");
printf("273 546 819\n");
printf("327 654 981\n");
return 0;
}
上面是dfs的函数,下面是用dfs求得得答案
没有一点问题
代码嘎嘎短
下一个
题目描述
用高精度计算出 S = 1! + 2! + 3! + \cdots + n!S=1!+2!+3!+⋯+n!(n \le 50n≤50)。
其中 !
表示阶乘,定义为 n!=n\times (n-1)\times (n-2)\times \cdots \times 1n!=n×(n−1)×(n−2)×⋯×1。例如,5! = 5 \times 4 \times 3 \times 2 \times 1=1205!=5×4×3×2×1=120。
输入格式
一个正整数 nn。
输出格式
一个正整数 SS,表示计算结果。
输入输出样例
输入 #1复制
3
输出 #1复制
9
说明/提示
【数据范围】
对于 100 \%100% 的数据,1 \le n \le 501≤n≤50。
【其他说明】
注,《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 n \le 20n≤20,使用书中的代码无法通过本题。
如果希望通过本题,请继续学习第八章高精度的知识。
出自:P1009 [NOIP1998 普及组] 阶乘之和 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这题目就是要用高精度方法去求
就是把一个数当成一位(每位最大不可以大于9的)
当成10进制就欧克了
边看代码边理解
#include<stdio.h>
int a[10005],b[10005];//b保留阶乘,a保留阶乘和
int i=1;
int l=1;//这个留阶乘与阶乘和的位数
int main(){
int n;
scanf("%d",&n);
a[1]=1;
b[1]=1;//初始化
for(int j=2;j<=n;j++){
int lj=i;
for(int h=1;h<=lj;h++){//先算j的阶乘b的值
b[h]=b[h]*j;
}
for(int h=1;h<=i;h++){//满10以上要进位
if(b[h]>=10){
b[h+1]=b[h+1]+b[h]/10;
b[h]=b[h]%10;
if(h==i){
b[i+1]=b[i+1]+b[i]/10;
b[i]=b[i]%10;
i++;
}
}
}
if(l<i){//阶乘和的位数不可能比阶乘小的
l=i;
}
for(int kl=1;kl<=i;kl++){//每位相加依然是满10进位但是由于是加法所以不会超过20 可以用a[l+1]++
a[kl]+=b[kl];
if(a[kl]>=10){
a[kl]=a[kl]%10;
a[kl+1]++;
}
}
if(a[l]>=10){//对最后的一位检查要是大于10就进位
a[l]=a[l]%10;
a[l+1]++;
l++;
}
}
for(int y=l;y>=1;y--){//用记录的位数从尾往前输出
printf("%d",a[y]);
}
return 0;
}
就是要有一个变量当一位数的思想,剩下的就是简单的加法和乘法了,以及满10进一的原则了
题目不难就是学点东西就可以了
ok下一个
题目描述
火车从始发站(称为第 11 站)开出,在始发站上车的人数为 aa,然后到达第 22 站,在第 22 站有人上、下车,但上、下车的人数相同,因此在第 22 站开出时(即在到达第 33 站之前)车上的人数保持为 aa 人。从第 33 站起(包括第 33 站)上、下车的人数有一定规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第 (n-1)(n−1) 站),都满足此规律。现给出的条件是:共有 nn 个车站,始发站上车的人数为 aa ,最后一站下车的人数是 mm(全部下车)。试问 xx 站开出时车上的人数是多少?
输入格式
输入只有一行四个整数,分别表示始发站上车人数 aa,车站数 nn,终点站下车人数 mm 和所求的站点编号 xx。
输出格式
输出一行一个整数表示答案:从 xx 站开出时车上的人数。
输入输出样例
输入 #1复制
5 7 32 4
输出 #1复制
13
说明/提示
对于全部的测试点,保证 1 \leq a \leq 201≤a≤20,1 \leq x \leq n \leq 201≤x≤n≤20,1 \leq m \leq 2 \times 10^41≤m≤2×104。
这题目,可太数学了
呜呜呜呜呜呜呜
我真的是无语,纯纯的数学题目
有个未知数就是在2站到底上了多少人
我们设为x
在本子上推导
每个站点增加的人数
a1=a;
a2=0;
a3=a;
a4=x;
a5=a+x;
a6=a+2x;
从推导可以看出从第5站后面人数就是一个斐波那契数列了
但是x是未知数,所以我们的任务就是求出x,但是程序不会公式,我们要想办法去实现
而且a和x要分开来求系数
呜呜呜,明明答案就在我的眼前但是我就是拿不到
上代码
出自:P1011 [NOIP1998 提高组] 车站 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<stdio.h>
int a[100];
int find(int hj){//这里是求x的系数
int u=0;
a[1]=0;
a[2]=0;
a[3]=0;
a[4]=1;
if(hj>4){
u++;
}
for(int jk=5;jk<hj;jk++){
a[jk]=a[jk-1]+a[jk-2];
u+=a[jk];
}
return u;
}
int main(){
int n;
int x;
int l;
int ans;
scanf("%d%d%d%d",&x,&n,&l,&ans);
int jk=find(n);
a[1]=0;
a[2]=0;
a[3]=1;
a[4]=0;
int lk=1;
if(n>3){
lk++;
}
for(int g=5;g<n;g++){//这里是求a的系数
a[g]=a[g-1]+a[g-2];
lk+=a[g];
}//两个系数到手解方程就可以了
int hj=l-x*lk;
int v=hj/jk;
int sum=x;
a[3]=x;
a[4]=v;
if(ans>=3){//得到了x就从新求一边得出答案
sum+=x;
}
if(ans>=4){
sum+=v;
}
for(int bn=5;bn<=ans;bn++){
a[bn]=a[bn-1]+a[bn-2];
sum+=a[bn];
}
printf("%d",sum);
return 0;
}
这是极少数,我感觉用程序比实际去解还要麻烦的现实问题。
肯定是我的方法有问题一定是的。
要是身边没有一支笔一个本子,我想这题目的难度还要上升几个档次
ok下一个
题目描述
任何一个正整数都可以用 22 的幂次方表示。例如 137=2^7+2^3+2^0137=27+23+20。
同时约定方次用括号来表示,即 a^bab 可表示为 a(b)a(b)。
由此可知,137137 可表示为 2(7)+2(3)+2(0)2(7)+2(3)+2(0)
进一步:
7= 2^2+2+2^07=22+2+20 ( 2^121 用 22 表示),并且 3=2+2^03=2+20。
所以最后 137137 可表示为 2(2(2)+2+2(0))+2(2+2(0))+2(0)2(2(2)+2+2(0))+2(2+2(0))+2(0)。
又如 1315=2^{10} +2^8 +2^5 +2+11315=210+28+25+2+1
所以 13151315 最后可表示为 2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)。
输入格式
一行一个正整数 nn。
输出格式
符合约定的 nn 的 0, 20,2 表示(在表示中不能有空格)。
输入输出样例
输入 #1复制
1315
输出 #1复制
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
说明/提示
【数据范围】
对于 100\%100% 的数据,1 \le n \le 2 \times {10}^41≤n≤2×104。
出自:P1010 [NOIP1998 普及组] 幂次方 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
本来是想老老实实的用dfs来写的可是看到数据确实不大,ok邪恶的想法出现了,
先打表,然后输出,数据很小,那笔写一写就可以了真的不要太爽
#include<stdio.h>
int main(){
char a[16][100]={"2(0)","2","2(2)","2(2+2(0))","2(2(2))","2(2(2)+2(0))","2(2(2)+2)","2(2(2)+2+2(0))","2(2(2+2(0)))","2(2(2+2(0))+1)","2(2(2+2(0))+2)","2(2(2+2(0))+2+2(0))","2(2(2+2(0))+2(2))","2(2(2+2(0))+2(2)+2(0))","2(2(2+2(0))+2(2)+2)","2(2(2+2(0))+2(2)+2+2(0))"};
int n;
int map[15]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384};
scanf("%d",&n);
for(int h=14;h>=0;h--){
if(n>=map[h]){
n=n-map[h];
printf("%s",a[h]);
if(n!=0){
printf("+");
}
else{
break;
}
}
}
return 0;
}
打表yyds
变成二进制完全没有问题,在加上提前备好的输出,直接秒杀
ok今天就到这把
我直接开溜!
byebye!!