P1303 A*B Problem
题目背景
高精度乘法模板题。
题目描述
给出两个非负整数,求它们的乘积。
输入格式
输入共两行,每行一个非负整数。
输出格式
输出一个非负整数表示乘积。
输入输出样例
输入 #1复制
1
2
输出 #1复制
2
说明/提示
每个非负整数不超过 102000。
实现代码:
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e7;
char a[N],b[N];
int s[N];
signed main(){
cin>>a+1;
cin>>b+1;
int s1=strlen(a+1);
int s2=strlen(b+1);
reverse(a+1,a+1+s1);
reverse(b+1,b+1+s2);
int t=0;
for(int i=1;i<=s1;i++){
for(int j=1;j<=s2;j++){
s[i+j-1]+=(a[i]-'0')*(b[j]-'0')+t;
t=s[i+j-1]/10;
s[i+j-1]=s[i+j-1]%10;
}
int len=i+s2;
if(t>0){
s[len]=t;
t=0;
}
}
int f=0;
if(s[s1+s2]==0){
for(int i=s1+s2-1;i>=1;i--){
if((s[i]!=0)||(s[i]==0&&f==1)){
cout<<s[i];
f=1;
}
}
if(f==0){
cout<<"0";
}
}
else{
for(int i=s1+s2;i>=1;i--){
cout<<s[i];
}
}
return 0;
}
P1009 [NOIP 1998 普及组] 阶乘之和
题目描述
用高精度计算出 S=1!+2!+3!+⋯+n!(n≤50)。
其中 ! 表示阶乘,定义为 n!=n×(n−1)×(n−2)×⋯×1。例如,5!=5×4×3×2×1=120。
输入格式
一个正整数 n。
输出格式
一个正整数 S,表示计算结果。
输入输出样例
输入 #1复制
3
输出 #1复制
9
说明/提示
【数据范围】
对于 100% 的数据,1≤n≤50。
【其他说明】
注,《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 n≤20,使用书中的代码无法通过本题。
如果希望通过本题,请继续学习第八章高精度的知识。
NOIP1998 普及组 第二题
实现代码:
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=111;
int a[N]={0},s[N]={0};
int n;
void fun(int x){
int t=0;
for(int i=100;i>=1;i--){
a[i]=a[i]*x+t;
t=a[i]/10;
a[i]=a[i]%10;
}
}
void f(){
int t=0;
for(int i=100;i>=1;i--){
s[i]+=a[i]+t;
t=s[i]/10;
s[i]=s[i]%10;
}
}
signed main(){
cin>>n;
a[100]=1;
for(int i=1;i<=n;i++){
fun(i);
f();
}
for(int i=1;i<=100;i++){
if(s[i]){
for(int j=i;j<=100;j++){
cout<<s[j];
}
return 0;
}
}
return 0;
}
P4924 [1007] 魔法少女小Scarlet
题目描述
Scarlet 最近学会了一个数组魔法,她会在 n×n 二维数组上将一个奇数阶方阵按照顺时针或者逆时针旋转 90∘。
首先,Scarlet 会把 1 到 n2 的正整数按照从左往右,从上至下的顺序填入初始的二维数组中,然后她会施放一些简易的魔法。
Scarlet 既不会什么分块特技,也不会什么 Splay 套 Splay,她现在提供给你她的魔法执行顺序,想让你来告诉她魔法按次执行完毕后的二维数组。
输入格式
第一行两个整数 n,m,表示方阵大小和魔法施放次数。
接下来 m 行,每行 4 个整数 x,y,r,z,表示在这次魔法中,Scarlet 会把以第 x 行第 y 列为中心的 2r+1 阶矩阵按照某种时针方向旋转,其中 z=0 表示顺时针,z=1 表示逆时针。
输出格式
输出 n 行,每行 n 个用空格隔开的数,表示最终所得的矩阵。
输入输出样例
输入 #1复制
5 4
2 2 1 0
3 3 1 1
4 4 1 0
3 3 2 1
输出 #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
说明/提示
对于 50% 的数据,满足 r=1;
对于 100% 的数据,满足 1≤n,m≤500,1≤x−r≤x+r≤n,1≤y−r≤y+r≤n。
实现代码:
cpp
#include<bits/stdc++.h>
using namespace std;
int g[510][510],tot,f[510][510];
int main(){
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
g[i][j]=++tot;
for(int i=1;i<=m;i++) {
int a,b,r,opt;
scanf("%d %d %d %d",&a,&b,&r,&opt);
if(opt==0) {
for(int i=a-r;i<=a+r;i++)
for(int j=b-r;j<=b+r;j++)
f[a-b+j][a+b-i] = g[i][j];
for(int i=a-r;i<=a+r;i++)
for(int j=b-r;j<=b+r;j++)
g[i][j] = f[i][j];
}
else {
for(int i=a-r;i<=a+r;i++)
for(int j=b-r;j<=b+r;j++)
f[a+b-j][b-a+i] = g[i][j];
for(int i=a-r;i<=a+r;i++)
for(int j=b-r;j<=b+r;j++)
g[i][j] = f[i][j];
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++)
printf("%d ",g[i][j]);
printf("\n");
}
return 0;
}
P1328 [NOIP 2014 提高组] 生活大爆炸版石头剪刀布
题目背景
NOIP2014 提高组 D1T1
题目描述
石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。在《生活大爆炸》第二季第 8 集中出现了一种石头剪刀布的升级版游戏。
升级版游戏在传统的石头剪刀布游戏的基础上,增加了两个新手势:
斯波克:《星际迷航》主角之一。
蜥蜴人:《星际迷航》中的反面角色。
这五种手势的胜负关系如表一所示,表中列出的是甲对乙的游戏结果。

现在,小 A 和小 B 尝试玩这种升级版的猜拳游戏。已知他们的出拳都是有周期性规律的,但周期长度不一定相等。例如:如果小 A 以 石头-布-石头-剪刀-蜥蜴人-斯波克 长度为 6 的周期出拳,那么他的出拳序列就是 石头-布-石头-剪刀-蜥蜴人-斯波克-石头-布-石头-剪刀-蜥蜴人-斯波克-...,而如果小 B 以 剪刀-石头-布-斯波克-蜥蜴人 长度为 5 的周期出拳,那么他出拳的序列就是 剪刀-石头-布-斯波克-蜥蜴人-剪刀-石头-布-斯波克-蜥蜴人-...。
已知小 A 和小 B 一共进行 N 次猜拳。每一次赢的人得 1 分,输的得 0 分;平局两人都得 0 分。现请你统计 N 次猜拳结束之后两人的得分。
输入格式
第一行包含三个整数:N,NA,NB,分别表示共进行 N 次猜拳、小 A 出拳的周期长度,小 B 出拳的周期长度。数与数之间以一个空格分隔。
第二行包含 NA 个整数,表示小 A 出拳的规律,第三行包含 NB 个整数,表示小 B 出拳的规律。其中,0 表示 剪刀,1 表示 石头,2 表示 布,3 表示 蜥蜴人,4 表示 斯波克。数与数之间以一个空格分隔。
输出格式
输出一行,包含两个整数,以一个空格分隔,分别表示小 A、小 B 的得分。
输入输出样例
输入 #1复制
10 5 6
0 1 2 3 4
0 3 4 2 1 0
输出 #1复制
6 2
输入 #2复制
9 5 5
0 1 2 3 4
1 0 3 2 4
输出 #2复制
4 4
说明/提示
对于 100% 的数据,0<N≤200,0<NA≤200,0<NB≤200 。
实现代码:
cpp
#include <iostream>
using namespace std;
int n, a, b, p[205],q[205], x, y;
int k[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 >> a >> b;
for (int i = 0; i < a; i++)
cin >> p[i];
for (int i = 0; i < b; i++)
cin >> q[i];
for (int i = 0; i < n; i++) {
x += k[p[i % a]][q[i % b]];
y += k[q[i % b]][p[i % a]];
}
cout << x << ' ' << y;
return 0;
}