> 文章列表 > 【洛谷题单算法1-1】P1303\\P1009\\P4924\\P1328

【洛谷题单算法1-1】P1303\\P1009\\P4924\\P1328

【洛谷题单算法1-1】P1303\P1009\P4924\P1328

P1303 A*B Problem

题目描述

给出两个非负整数,求它们的乘积。

输入格式

输入共两行,每行一个非负整数。

输出格式

输出一个非负整数表示乘积。

输入输出样例

输入

1 
2

输出

2

代码如下

#include<iostream>
#include<string>
using namespace std;  
int a[5010],b[5010],c[5010];  //两个数及乘积 
int lena,lenb,lenc,i,j,k;  
void mult(int a[],int b[]){for(i=0; i<lena; i++){for(j=0; j<lenb; j++){k=i+j;c[k]+=a[i]*b[j];while(c[k]>=10){c[k+1]+=c[k]/10;  //加上原数值 c[k]%=10;k++;  //下标改变 }}}lenc=lena+lenb;while(c[lenc]==0) lenc--;
}int main(){string s1,s2;  //两个数 cin>>s1>>s2;lena=s1.size(); lenb=s2.size();for( i=0; i<lena; i++){  //字符倒序存入数组中 a[lena-i-1]=s1[i]-'0';}for( i=0; i<lenb; i++){b[lenb-i-1]=s2[i]-'0';}//mult乘法 mult(a,b);if(lenc<0) cout<<0; for( i=lenc; i>=0; i--){cout<<c[i];}return 0;
}

P1009 [NOIP1998 普及组] 阶乘之和

题目描述

用高精度计算出 S=1!+2!+3!+⋯+n!S = 1! + 2! + 3! + \\cdots + n!S=1!+2!+3!++n!n≤50n \\le 50n50)。

其中 ! 表示阶乘,定义为 n!=n×(n−1)×(n−2)×⋯×1n!=n\\times (n-1)\\times (n-2)\\times \\cdots \\times 1n!=n×(n1)×(n2)××1。例如,5!=5×4×3×2×1=1205! = 5 \\times 4 \\times 3 \\times 2 \\times 1=1205!=5×4×3×2×1=120

输入格式

一个正整数 n。

输出格式

一个正整数 S,表示计算结果。

输入输出样例

输入

3

输出

9

代码如下

#include<iostream>
#include<algorithm>  //fill赋值(begin, end, value) 
using namespace std;  
int a[5010],b[5010];
int i,j;int main(){int n;cin>>n;//fill(a+1,a+20,1);  //a数组初始化为1; a[1]=1,b[1]=1;int l=1;  //l表示(i-1)!的最高位 //高精度乘法for(i=2; i<=n; i++){for(j=1; j<=l; j++){a[j]*=i;  //(i-1)!的每一位乘i } for(j=1; j<=l; j++){  //处理进位 while(a[j]>=10){a[j+1]+=a[j]/10;a[j]%=10;}}while(a[l+1]>0){  //处理最高位产生的进位 l+=1;a[l+1]=a[l]/10;a[l]%=10;}//	if(a[l+1]>0) l++; //高精度加法for(j=1; j<=l; j++){  //a[j]为第i个数阶乘,b[j]为前i-1个数的阶乘和 b[j]=a[j]+b[j];while(b[j]>=10){b[j+1]+=b[j]/10;b[j]%=10;}}} for(i=l; i>=1; i--){cout<<b[i];}return 0;
}

P4924 [1007]魔法少女小Scarlet

题目描述

Scarlet 最近学会了一个数组魔法,她会在 n×nn\\times nn×n 二维数组上将一个奇数阶方阵按照顺时针或者逆时针旋转 90∘90^\\circ90

首先,Scarlet 会把 1 到 n2n^2n2 的正整数按照从左往右,从上至下的顺序填入初始的二维数组中,然后她会施放一些简易的魔法。

Scarlet 既不会什么分块特技,也不会什么 Splay 套 Splay,她现在提供给你她的魔法执行顺序,想让你来告诉她魔法按次执行完毕后的二维数组。

输入格式

第一行两个整数 n,mn,mn,m,表示方阵大小和魔法施放次数。

接下来 m 行,每行 4 个整数 x,y,r,zx,y,r,zx,y,r,z,表示在这次魔法中,Scarlet 会把以第 x 行第 y 列为中心的 2r+12r+12r+1 阶矩阵按照某种时针方向旋转,其中 z=0z=0z=0 表示顺时针,z=1z=1z=1 表示逆时针。

输出格式

输出 n 行,每行 n 个用空格隔开的数,表示最终所得的矩阵

输入输出样例

输入

5 4
2 2 1 0
3 3 1 1
4 4 1 0
3 3 2 1

输出

5 10 3 18 15
4 19 8 17 20
1 14 23 24 25
6 9 2 7 22
11 12 13 16 21

代码如下

#include<iostream>
using namespace std;int a[510][510],b[510][510];
int i,j,k;   
int n,m,x,y,r,z;  //(x,y)位置,2r+1为长度,z=0顺时针旋转,z=1逆时针 
void rotate(){if(z==0){  //顺时针  以原点分析旋转后位置,再以(x,y)分析 for(i=x-r; i<=x+r; i++){ for(j=y-r; j<=y+r; j++){b[j-y+x][y-i+x]=a[i][j];}} }else{  //逆时针 for(i=x-r; i<=x+r; i++){for(j=y-r; j<=y+r; j++){  b[x-j+y][i-x+y]=a[i][j];   }} }for(i=x-r; i<=x+r; i++){  //更新a数组的值,为下一次旋转做准备 for(j=y-r; j<=y+r; j++){a[i][j]=b[i][j];}} 
} int main(){cin>>n>>m;  //n阶矩阵,m条指令 for(i=1; i<=n; i++) {for(j=1; j<=n; j++){a[i][j]=(i-1)*n+j;  //存入二阶矩阵 b[i][j]=(i-1)*n+j;   //转换用 }}for(k=1; k<=m; k++){   cin>>x>>y>>r>>z;rotate();   //rotate旋转 } for(i=1; i<=n; i++) {  //输出 for(j=1; j<=n; j++){cout<<a[i][j]<<" ";  }cout<<endl;}return 0;
}

P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀

题目描述

石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。在《生活大爆炸》第二季第 8 集中出现了一种石头剪刀布的升级版游戏。

升级版游戏在传统的石头剪刀布游戏的基础上,增加了两个新手势:

斯波克:《星际迷航》主角之一。

蜥蜴人:《星际迷航》中的反面角色。

这五种手势的胜负关系如表一所示,表中列出的是甲对乙的游戏结果。
【洛谷题单算法1-1】P1303\P1009\P4924\P1328
现在,小 A 和小 B 尝试玩这种升级版的猜拳游戏。已知他们的出拳都是有周期性规律的,但周期长度不一定相等。例如:如果小 A 以“石头-布-石头-剪刀-蜥蜴人-斯波克”长度为 6 的周期出拳,那么他的出拳序列就是“石头-布-石头-剪刀-蜥蜴人-斯波克-石头-布-石头-剪刀-蜥蜴人-斯波克-…”,而如果小 B 以“剪刀-石头-布-斯波克-蜥蜴人”长度为 5 的周期出拳,那么他出拳的序列就是“剪刀-石头-布-斯波克-蜥蜴人-剪刀-石头-布-斯波克-蜥蜴人-…”

已知小 A 和小 B 一共进行 N 次猜拳。每一次赢的人得 1 分,输的得 0 分;平局两人都得 0 分。现请你统计 N 次猜拳结束之后两人的得分。

输入格式

第一行包含三个整数:N,NA,NBN,N_A,N_BN,NA,NB,分别表示共进行 N 次猜拳、小 A 出拳的周期长度,小 B 出拳的周期长度。数与数之间以一个空格分隔。

第二行包含 NAN_ANA 个整数,表示小 A 出拳的规律,第三行包含 NBN_BNB个整数,表示小 B 出拳的规律。其中,0 表示“剪刀”,1 表示“石头”,2 表示“布”,3 表示“蜥蜴人”,4表示“斯波克”。数与数之间以一个空格分隔。

输出格式

输出一行,包含两个整数,以一个空格分隔,分别表示小 A、小 B 的得分。

输入输出样例

输入

10 5 6
0 1 2 3 4
0 3 4 2 1 0

输出

6 2

代码如下

#include<bits/stdc++.h>//万能头文件
using namespace std;
int n,na,nb,i;
int a[210],b[210];  //a、b分别代表小A、小B的出拳周期 
int cnta,cntb;  //记录A、B的得分 
//0 表示“剪刀”,1 表示“石头”,2 表示“布”,3 表示“蜥蜴人”,4表示“斯波克” 
int ans[5][5] ={{0,0,1,1,0},{1,0,0,1,0},  //打得分表 {0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}};int main()
{cin>>n>>na>>nb;for(i=1; i<=na; i++) cin>>a[i];   //a的出拳顺序 for(i=1; i<=nb; i++) cin>>b[i];  //b的出拳顺序 for(i=1; i<=n; i++){if(ans[a[(i-1)%na+1]][b[(i-1)%nb+1]])  cnta++;  //对A的结果 if(ans[b[(i-1)%nb+1]][a[(i-1)%na+1]])  cntb++;  //对B的结果} cout<<cnta<<" "<<cntb;return 0;
}