A 求N!的值
【问题描述】
用高精度方法,求N!的精确值(N以一般整数输入)。
【输入形式】
【输出形式】
【样例输入】
10
【样例输出】
3628800
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue>
# include<map>
# include<string>
# include<cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII;
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846;
int n;
int a[2005];
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
a[0] = 1;
for(int i = 1 ; i <= n ; i ++ ){
int b = 0 ;
int s;
for(int j = 0 ; j < 2000 ; j ++ ){
s = a[j] * i + b;
a[j] = s % 10;
b = s / 10;
}
}
int i;
for(i = 2004 ; i >= 0 ; i-- )
if(a[i] != 0) break;
for(int j = i ; j >= 0 ; j--)
cout<<a[j];
return 0;
}
B 求A/B高精度值
【问题描述】
计算A/B的精确值,设A,B是以一般整数输入,计算结果精确到小数后20位(若不足20位,末尾不用补0)。
【输入形式】
【输出形式】
【样例输入1】
4 3
【样例输出1】
4/3=1.33333333333333333333
【样例输入2】
6 5
【样例输出2】
6/5=1.2
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue>
# include<map>
# include<string>
# include<cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII;
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846;
int a,b;
int c[25];
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> a >> b;
cout<< a<<"/"<<b<<"=" <<a/b<<".";
for(int i = 1 ; i <= 20 ; i++ ){
a = a % b ;
a = a * 10;
c[i] = a / b ;
}
int i = 20;
while(c[i] == 0 && i >=0 ) i--;
for(int j = 1 ; j <= i ; j++)
cout<<c[j];
return 0;
}
C 求n累加和
【问题描述】
用高精度方法,求s=1+2+3+……+n的精确值(n以一般整数输入)。
【输入形式】
【输出形式】
【样例输入】
10
【样例输出】
55
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue>
# include<map>
# include<string>
# include<cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII;
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846;
ll a[2005],b[2005],c[2005],d[2005];
ll n;
void change(int num,ll a[]){
int cnt = 0;
while(num/10){
a[++cnt] = num%10;
num/=10;
}
while(num/10 == 0 && num >0){
a[++cnt] = num;
num/=10;
}
a[0] = cnt;
}
void add(ll a[],ll c[]){
int i , x = 0;
for( i = 1 ; i <= a[0] || i <= c[0] ; i++ ){
c[i] = c[i] + a[i] + x;
x = c[i] / 10;
c[i] = c[i] % 10;
}
c[i] = x;
if(c[i] == 0 ) c[0] = i - 1;
else c[0] = i;
}
void cf(ll a[],ll b[],ll c[]){
int i , j ;
for(int i = 1 ; i <= b[0] ; i ++){
int x;
for(int j = 1 , x = 0 ; j <= a[0] ; j++ ){
c[i+j-1] += a[j] * b[i] + x;
x = c[i+j-1]/10;
c[i+j-1]%=10;
}
c[i+a[0]] = x;
}
int l = a[0] + b[0];
while(c[l] == 0 && l > 1) l--;
c[0] = l;
}
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n ;
change(n + 1 , a);
change(n / 2 , b);
cf(a , b , c);
if(n&1){
change(n/2+1,d);
add(d,c);
}
for(int j = c[0] ; j >= 1 ; j-- )
cout<<c[j];
return 0;
}
D 阶乘和
【问题描述】
已知正整数N(N<=100),设S=1!+2!+3!+…N!。其中"!"表示阶乘,即N!=123*……(N-1)N,如:3!=123=6。请编程实现:输入正整数N,输出计算结果S的值。
【输入形式】
【输出形式】
【样例输入】
4
【样例输出】
33
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue>
# include<map>
# include<string>
# include<cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII;
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846;
int n;
int t[MAX],res[MAX],len = 1,reslen;
void jiechen(int v){
for(int i = 1 ; i <= len ; i ++ )
t[i] = t[i] * v;
int i=1;
while(t[i]>9||i<len)
{
t[i+1]+=t[i]/10;
t[i]%=10;
i++;
}
len=i;
}
void add(){
for(int i=1;i<=len;i++)
{
res[i]+=t[i];
if(res[i]>9)
{
res[i+1]+=res[i]/10;
res[i]%=10;
reslen=max(reslen,i+1);
}
reslen=max(reslen,i);
}
}
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
t[1] = 1;
for(int i = 1 ; i <= n ; i++ ) jiechen(i),add();
for(int i = reslen ; i >=1;i--)
cout<<res[i];
return 0;
}
E 高精度求积
【问题描述】
输入两个高精度正整数M和N(M和N均小于100位)。
求这两个高精度数的积。
【输入形式】
输入两个高精度正整数M和N。
【输出形式】
求这两个高精度数的积。
【样例输入】
36
3
【样例输出】
108
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue>
# include<map>
# include<string>
# include<cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII;
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846;
string s1,s2;
int a[MAX],b[MAX],c[MAX];
int len1,len2,len3;
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> s1 >> s2;
if(s1[0] == '0' || s2[0] == '0'){
cout<<0;
return 0;
}
len1 = s1.length() ;
len2 = s2.length() ;
for(int i = 0 ; i < len1 ; i ++ )
a[len1 - i ] = s1[i] - '0';
for(int i = 0 ; i < len2 ; i ++ )
b[len2 - i ] = s2[i] - '0';
for(int i = 1 ; i <= len2 ; i++ ){
int k = 0;
for(int j = 1 ; j <= len1 ; j ++){
c[i + j - 1] = a[j] * b[i] + c[i+j-1];
k=c[i + j - 1]/10;
c[i + j - 1]%=10;
c[i + j] += k;
}
}
len3=len1+len2;
for(int j=len3;j>=1;j--)
if(c[j]!=0) break;
else len3--;
for(int j=len3;j>=1;j--)
cout<<c[j];
return 0;
}
F 天使的起誓
【问题描述】
TENSHI非常幸运地被选为掌管智慧之匙的天使。在正式任职之前,她必须和其他新当选的天使一样,要宣誓。宣誓仪式是每位天使各自表述自己的使命,她们的发言稿被放在n 个呈圆形排列的宝盒中。这些宝盒按顺时针方向被编上号码1、2、3……、n-1、n。一开始天使们站在编号为N 的宝盒旁。她们各自手
上都有一个数字,代表她们自己的发言稿所在的盒子是从1号盒子开始按顺时针方向的第几个。例如:有7个盒子,那么如果TENSHI 手上的数字为9,那么她的发言稿所在盒子就是第2 个。现在天使们开始按照自己手上的数字来找发言稿,先找到的就可以先发言。TENSHI 一下子就找到了,于是她最先上台宣誓:“我将带领大家开启NOI 之门……”TENSHI 宣誓结束以后,陆续有天使上台宣誓。可是有一位天使找了好久都找不到她的发言稿,原来她手上的数字M 非常大,她转了好久都找不到她想找的宝盒。请帮助这位天使找到她想找的宝盒的编号。
【输入形式】
从文件 的第一、二行分别读入正整数n 和m,其中n、m 满足 2 ≤ n≤ 108,2 ≤ m≤ 101000
【输出形式】
把所求宝盒的编号输出,文件只有一行(包括换行符)。
【样例输入1】
7
9
【样例输出1】
2
【样例输入2】
11
108
【样例输出2】
9
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue>
# include<map>
# include<string>
# include<cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII;
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846;
int n;
ll ans ;
char s[MAX];
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
string s;
cin >> n >> s;
for(int i=0;s[i] ;i++)
ans=(ans*10+s[i]-'0')%n;
if(ans == 0 ) cout<<n;
else cout<<ans;
return 0;
}
G Hanoi 双塔问题
【问题描述】
给定A、B、C 三根足够长的细柱,在A 柱上放有2n 个中间有孔的圆盘,共有n 个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为n=3 的情形)。现要将这些圆盘移到C 柱上,在移动过程中可放在B 柱上暂存。要求:
(1)每次只能移动一个圆盘;
(2)A、B、C 三根细柱上的圆盘都要保持上小下大的顺序;任务:设An为2n个圆盘完成上述任务所需的最少移动次数,对于输入的n,输出An。
【输入形式】
输入文件为一个正整数n,表示在A 柱上放有2n 个圆盘。
【输出形式】
输出仅一行,包含一个正整数, 为完成上述任务所需的最少移动次数An。
【样例输入1】
1
【样例输出1】
2
【样例输入2】
2
【样例输出2】
6
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue>
# include<map>
# include<string>
# include<cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII;
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846;
int n ,a[205],b[205];
void gjc(){
int t = 0,k;
for(int j = 200 ; j > 0 ;j--){
k = b[j] * 2 + t;
b[j] = k % 10;
t = k / 10;
}
}
void gjj(){
int t = 0 ,k;
for(int j = 200 ; j > 0 ; j-- ){
k = a[j] + b[j] + t;
a[j] = k % 10;
t = k / 10;
}
}
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
b[200] = 1;
for(int i = 1;i <= n ; i++) gjc(),gjj();
int k = 1;
while(a[k] == 0 && k < 200) k ++ ;
for(int i = k ; i <= 200 ; i++ )
cout<<a[i];
return 0;
}
H 高精除
【问题描述】
高精除以高精,求它们的商和余数。
【输入形式】
输入两个低于300位的正整数。
【输出形式】
输出商和余数。
【样例输入】
1231312318457577687897987642324567864324567876543245671425346756786867867867
1231312318767141738178325678412414124141425346756786867867867
【样例输出】
999999999748590
179780909068307566598992807564736854549985603543237528310337
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int a[101], b[101], c[101], d;
void init(int a[]) {
string s;
cin >> s; // 读入字符串s
a[0] = s.length(); // 用a[0]计算字符串s的位数
for (int i=1; i<=a[0]; i++) {
a[i] = s[a[0]-i] - 48; // 将数串s转换为数组a,并倒序存储
}
}
void print(int a[]) { // 打印输出
if (a[0] == 0) {
cout << 0 << endl;
return;
}
for (int i=a[0]; i>=1; i--) {
cout << a[i];
}
cout << endl;
return;
}
int compare(int a[], int b[]) { // 比较a和b的大小关系,若a>b则为1,a<b则为-1,a=b则为0
if (a[0] > b[0]) {
return 1;
}
if (a[0] < b[0]) {
return -1;
}
for (int i=a[0]; i>=1; i--) { // 从高位到低位比较
if (a[i] > b[i]) {
return 1;
}
if (a[i] < b[i]) {
return -1;
}
}
return 0; // 各位都相等则两数相等
}
void numcpy(int p[], int q[], int det) { // 复制p数组到q数组从det开始的地方
for (int i=1; i<=p[0]; i++) {
q[i+det-1] = p[i];
}
q[0] = p[0] + det - 1;
}
void jian(int a[], int b[]) { // 计算 a=a-b
int flag = compare(a, b); // 调用比较函数判断大小
if (flag == 0) { // 相等
a[0] = 0;
return;
}
if (flag == 1) { // 大于
for (int i=1; i<=a[0]; i++) {
if (a[i] < b[i]) {
a[i+1]--; // 若不够减,则向上借一位
a[i] += 10;
}
a[i] -= b[i];
}
while (a[0]>0 && a[a[0]]==0) {
a[0]--; // 修正a的位数
}
return;
}
}
void chugao(int a[], int b[], int c[]) {
int tmp[101];
c[0] = a[0] - b[0] + 1;
for (int i=c[0]; i>0; i--) {
memset(tmp, 0, sizeof(tmp)); // 数组清零
numcpy(b, tmp, i);
while (compare(a, tmp) >= 0) {
c[i]++;
jian(a, tmp);
// 用减法来模拟
}
}
while (c[0]>0 && c[c[0]]==0) {
c[0]--;
}
return;
}
int main() {
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
init(a);
init(b);
chugao(a,b,c);
print(c);
print(a);
return 0;
}
I 回文数
【问题描述】
若一个数(首位不为零)从左向右读与从右向左读都是一样,我们就将其称之为回文数。例如:给定一个 10进制数 56,将 56加 65(即把56从右向左读),得到 121是一个回文数。又如,对于10进制数87,
STEP1: 87+78= 165 STEP2: 165+561= 726
STEP3: 726+627=1353 STEP4:1353+3531=4884
在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884。
写一个程序,给定一个N(2<N<=10或N=16)进制数 M.求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!” 。
【输入形式】
给定一个N(2<N<=10或N=16)进制数M。
【输出形式】
最少几步。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”。
【样例输入】
9 87
【样例输出】
STEP=6
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue>
# include<map>
# include<string>
# include<cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII;
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846;
char c[305],d[305];
int n,step,len;
void add(){
for(int i = 0 ; i < len ; i ++)
d[len - i - 1] = c[i];
len += 2 ;
for(int i = 0 ; i < len ; i ++ ){
c[i] += d[i];
if(c[i] >= n) c[i+1] ++, c[i] -= n;
}
while(!c[len - 1]) len -- ;
}
int judge(){
for(int i = 0 ; i < len ; i ++){
if(c[i] != c[len - 1 - i]) return 0;
}
return 1;
}
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> c;
len = strlen(c);
for(int i = 0 ; c[i] ; i ++ ){
if(c[i] >='0' && c[i] <='9') c[i] -= '0';
else c[i] = c[i] - 'A' + 10;
}
while(!judge()){
step++;
if(step>30) break;
add();
}
if(step <= 30) cout<<"STEP="<<step;
else cout<<"Impossible!";
return 0;
}