51NOD 基础题全部题解(更新中......)

 

目录

1000 A + B ​

题解:

1005 大数加法 ​

题解:

1006 最长公共子序列Lcs ​

题解:

1008 N的阶乘 mod P ​

题解:

1011 最大公约数GCD ​

题解:

1012 最小公倍数LCM ​

题解:

1018 排序 ​

题解:可以参考快排详细解答

1019 逆序数 ​

题解:归并排序查找逆序对

1027 大数乘法 ​

题解:

1046 A^B Mod C ​

题解:

1049 最大子段和 ​

题解:

1057 N的阶乘 ​

题解:

1058 N的阶乘的长度 ​

题解:

1066 Bash游戏 ​

        题解:

1069 Nim游戏 ​

题解:


 


1000 A + B 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

给出2个整数A和B,计算两个数的和。

Input

2个整数A B,中间用空格分割。(0 <= A, B <= 10^9)

Output

输出A + B的计算结果。

Input示例

1 2

Output示例

3

题解:

#include<bits/stdc++.h>
using namespace std;

int main(){
    int a,b;
    cin>>a>>b;
    cout<<a+b<<endl;
}

 

 

1005 大数加法 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

给出2个大整数A,B,计算A+B的结果。

Input

第1行:大数A
第2行:大数B
(A,B的长度 <= 10000 需注意:A B有可能为负数)

Output

输出A + B

Input示例

68932147586
468711654886

Output示例

537643802472

题解:

java:

import java.util.*;
import java.io.*;
import java.lang.String;
import java.math.BigDecimal;

public class nod {
    public static void main(String[] args) {
        String a,b;
        Scanner cin=new Scanner(System.in);
        a=cin.next();
        b=cin.next();
        BigDecimal a1=new BigDecimal(a);
        BigDecimal b1=new BigDecimal(b);
        System.out.println(a1.add(b1));
        cin.close();
    }
}

python3:

a=int(input())
b=int(input())
print(a+b)

1006 最长公共子序列Lcs 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。

比如两个串为:

 

abcicba

abdkscab

 

ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。

Input

第1行:字符串A
第2行:字符串B
(A,B的长度 <= 1000)

Output

输出最长的子序列,如果有多个,随意输出1个。

Input示例

abcicba
abdkscab

Output示例

abca

题解:

C++:

/*
题解:
    dp[i][j]={
                dp[i-1][j-1]+1                 ,s[i]==ss[j]
                max(dp[i-1][j],dp[i][j-1])     ,i>0 && j>0
                0                              ,i=0 || j=0
              }
    标记回溯,从尾向前

*/


#include<bits/stdc++.h>

using namespace std;
const int maxn=1e3+10;
int dp[maxn][maxn],vis[maxn][maxn];
char s[maxn],ss[maxn];

void print(int n,int m){
	if(n==0 || m==0) return;
	if(vis[n][m]==1){
		print(n-1,m-1);
		printf("%c",s[n-1]);
	}else if(vis[n][m]==2){
		print(n-1,m);
	}else print(n,m-1);
}

int main(){
	scanf("%s",s);
	scanf("%s",ss);
	memset(dp,0,sizeof(dp));
	memset(vis,0,sizeof vis);
	int len1=strlen(s),len2=strlen(ss);
	for(int i=1;i<=len1;i++){
		for(int j=1;j<=len2;j++){
			if(s[i-1]==ss[j-1]){
				dp[i][j]=dp[i-1][j-1]+1;
				vis[i][j]=1;
			}else if(dp[i-1][j]>dp[i][j-1]){
				dp[i][j]=dp[i-1][j];
				vis[i][j]=2;
			}else{
				dp[i][j]=dp[i][j-1];
				vis[i][j]=3; 
			}
		}
	}
// 	printf("%d\n",dp[len1][len2]);
	print(len1,len2);
} 

 

1008 N的阶乘 mod P 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

输入N和P(P为质数),求N! Mod P = ? (Mod 就是求模 %)

例如:n = 10, P = 11,10! = 3628800

3628800 % 11 = 10

Input

两个数N,P,中间用空格隔开。(N < 10000, P < 10^9)

Output

输出N! mod P的结果。

Input示例

10 11

Output示例

10

题解:

C++:

#include<bits/stdc++.h>

using namespace std;


int main(){
    int n,p;
    while(~scanf("%d%d",&n,&p)){
        long long sum=1;
        for(int i=1;i<=n;i++){
            sum=(sum*i)%p;
        }
        printf("%lld\n",sum);
    }
    return 0;
}

1011 最大公约数GCD 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

输入2个正整数A,B,求A与B的最大公约数。

Input

2个数A,B,中间用空格隔开。(1<= A,B <= 10^9)

Output

输出A与B的最大公约数。

Input示例

30 105

Output示例

15

题解:

C++:

#include<bits/stdc++.h>

using namespace std;

int gcd(int a,int b) {
    return b==0?a:gcd(b,a%b);
}

int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        printf("%d\n",gcd(n,m));
    }
}

1012 最小公倍数LCM 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

输入2个正整数A,B,求A与B的最小公倍数。

Input

2个数A,B,中间用空格隔开。(1<= A,B <= 10^9)

Output

输出A与B的最小公倍数。

Input示例

30 105

Output示例

210

题解:

C++:

#include<bits/stdc++.h>

using namespace std;

long long gcd(int x,int y){
	return y==0?x:gcd(y,x%y);
}

int main(){
	int a,b;
	scanf("%d%d",&a,&b); 
	printf("%lld\n",(long long)a*b/gcd(a,b)); 
} 

Python:

'''
三目运算符:
    条件在中间
'''

def gcd(a,b):
    return a if b==0 else gcd(b,a%b)
f = input().split(' ')
a=int(f[0])
b=int(f[1])
print('%.0f' %(a*b/gcd(a,b)))

1018 排序 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

给出N个整数,对着N个整数进行排序

Input

第1行:整数的数量N(1 <= N <= 50000)
第2 - N + 1行:待排序的整数(-10^9 <= A[i] <= 10^9)

Output

共n行,按照递增序输出排序好的数据。

Input示例

5
5
4
3
2
1

Output示例

1
2
3
4
5

题解:可以参考快排详细解答

C++:

#include<bits/stdc++.h>

using namespace std;
const int maxn=1e4+10;
int a[5*maxn];

int main(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	sort(a,a+n);
	for(int i=0;i<n;i++) printf("%d\n",a[i]);
} 

Python:

def inp(a,number):
    for i in range(number):
        a.append(int(input()))

def quick_sort(a,l,r):
    if l<r:
        i,j=l,r
        x = a[i]
        while i<j:
            while i<j and a[j]>x:
                j=j-1
            if i<j :
                a[i]=a[j]
                i=i+1
            while i<j and a[i]<x:
                i=i+1
            if i<j :
                a[j]=a[i]
                j=j-1
        a[i]=x
        quick_sort(a,l,i-1)
        quick_sort(a,i+1,r)

def output(n):
    for i in range(n):
        print(a[i])

if __name__=='__main__':
    a = []
    n = int(input())
    inp(a,n)
    quick_sort(a,0,n-1)
    output(n)

1019 逆序数 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。

如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。

Input

第1行:N,N为序列的长度(n <= 50000)
第2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9)

Output

输出逆序数

Input示例

4
2
4
3
1

Output示例

4

题解:归并排序查找逆序对

C++:

/*
直接归并排序
*/

#include<bits/stdc++.h>

using namespace std;
const int maxn=1e4+10;
int a[5*maxn],ans=0,temp[5*maxn];

void solve(int l,int r){
	int mid=(l+r)>>1;
	if(l<r){
		solve(l,mid);
		solve(mid+1,r);
		int k=l,i,j;
		for(i=l,j=mid+1;i<=mid && j<=r ;){
			if(a[i]>a[j]){
				temp[k++]=a[j++];
				ans+=mid-i+1;            //左边是已经排好序 
			}else temp[k++]=a[i++];
		}
		while(i<=mid) temp[k++]=a[i++];
		while(j<=r) temp[k++]=a[j++];
		for(int i=l;i<=r;i++){
			a[i]=temp[i];
		}
	}
}


int main(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	ans=0;
	solve(0,n-1);
	printf("%d\n",ans);
} 

Python:

/*
1.全局变量的定义
2.在函数需要声明全局变量
3.没有自加功能
4.在数组后面加入内容需要使用append
5.temp = [0 for i in range(50010)]数组声明
*/

global ans
def inp(a,number):
    for i in range(number):
        a.append(int(input()))

def solve(a,temp,l,r):
    mid = int((l+r)>>1)
    if l<r:
        solve(a,temp,l,mid)
        solve(a,temp,mid+1,r)
        k=l
        j=mid+1
        i=l
        while(i<=mid and j<=r):
            if a[i]>a[j]:
               temp[k]=a[j]
               k=k+1
               j=j+1
               global ans
               ans=ans+mid-i+1
            else:
                temp[k]=a[i]
                k=k+1
                i=i+1
        while i<=mid:
            temp[k]=a[i]
            k=k+1
            i=i+1
        while j<=r:
            temp[k]=a[j]
            k=k+1
            j=j+1
        for i in range(l,r+1):
            a[i]=temp[i]
    
def output(n):
    for i in range(n):
        print(a[i])

if __name__=='__main__':
    a = []
    temp = [0 for i in range(50010)]
    ans = 0
    n = int(input())
    inp(a,n)
    solve(a,temp,0,n-1)
    print(ans)

 

1027 大数乘法 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

给出2个大整数A,B,计算A*B的结果。

Input

第1行:大数A
第2行:大数B
(A,B的长度 <= 1000,A,B >= 0)

Output

输出A * B

Input示例

123456
234567

Output示例

28958703552

题解:

Java:

public class nod1 {
    public static void main(String[] args) {
        String a,b;
        Scanner cin=new Scanner(System.in);
        a=cin.next();
        b=cin.next();
        BigDecimal a1=new BigDecimal(a);
        BigDecimal b1=new BigDecimal(b);
        System.out.println(a1.multiply(b1));
        cin.close();
    }
}

Python:

if __name__=='__main__':
    a=int(input())
    b=int(input())
    print(a*b)

 

1046 A^B Mod C 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

给出3个正整数A B C,求A^B Mod C。

例如,3 5 8,3^5 Mod 8 = 3。

Input

3个正整数A B C,中间用空格分隔。(1 <= A,B,C <= 10^9)

Output

输出计算结果

Input示例

3 5 8

Output示例

3

题解:

Python:

def pow1(a,b,c):
    ans = 1
    temp = a
    while b:
        if (b&1):
            ans=(ans*temp)%c
        temp = (temp*temp)%c
        b>>=1
    return ans

if __name__=='__main__':
    f=input().split(' ')
    a = int(f[0])
    b = int(f[1])
    c = int(f[2])
    print(pow1(a,b,c))

 

1049 最大子段和 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

N个整数组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的连续子段和的最大值。当所给的整数均为负数时和为0。

例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。

Input

第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)

Output

输出最大子段和。

Input示例

6
-2
11
-4
13
-5
-2

Output示例

20

题解:

Python:

def ind(a,n):
    for i in range(0,n):
        a.append(int(input()))


if __name__=='__main__':
    n = int(input())
    a = []
    ind(a,n)
    maxn = -0x3f3f3f3f
    sum = 0
    for i in range(0,n):
        if sum < 0:            //当前值和 小于0 就将当前值 赋给sum
            sum = a[i]
        else :
            sum += a[i]        //负责相加   , 因为正数的值对后面的情况都有贡献
        maxn=max(sum,maxn)
    print(maxn)

 

1057 N的阶乘 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

输入N求N的阶乘的准确值。

Input

输入N(1 <= N <= 10000)

Output

输出N的阶乘

Input示例

5

Output示例

120

题解:

C++:

#include<bits/stdc++.h>

using namespace std;
const int maxn=1e5+10;
const int _MAXN = 1e8;
long long a[maxn];        //1e8乘一个数可能爆int

int main(){
	int n;
	scanf("%d",&n);
	int m=0;
	a[0]=1;
	for(int i=2;i<=n;i++){
		int c=0;
		for(int j=0;j<=m;j++){
			a[j] = a[j]*i+c;
			c = a[j]/_MAXN;
			a[j] %= _MAXN;
		}
		if(c){
			m++;
			a[m]=c;
		}
	}
	printf("%lld",a[m]);
	for(int i=m-1;i>=0;i--){
		printf("%08lld",a[i]); 
	}
} 

Python:

if __name__=='__main__':
    n = int(input())
    sum =1
    for i in range(1,n+1):
        sum *= i
    print(sum)

1058 N的阶乘的长度 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

输入N求N的阶乘的10进制表示的长度。例如6! = 720,长度为3。

Input

输入N(1 <= N <= 10^6)

Output

输出N的阶乘的长度

Input示例

6

Output示例

3

题解:

Python:

/*
斯特灵公式:
    n!=sqrt(2*PI*n)*(n/e)^n

    整数的位数:log(10,x)=n    10^n = x   位数:n+1

    得:int((0.5*math.log(2*3.1415926*n)+n*math.log(n)-n)/math.log(10))

*/
import math
if __name__=='__main__':
    n = int(input())
    ans = int((0.5*math.log(2*3.1415926*n)+n*math.log(n)-n)/math.log(10))
    print(ans+1)

1066 Bash游戏 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

有一堆石子共有N个。A B两个人轮流拿,A先拿。每次最少拿1颗,最多拿K颗,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N和K,问最后谁能赢得比赛。

例如N = 3,K = 2。无论A如何拿,B都可以拿到最后1颗石子。

Input

第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
第2 - T + 1行:每行2个数N,K。中间用空格分隔。(1 <= N,K <= 10^9)

Output

共T行,如果A获胜输出A,如果B获胜输出B。

Input示例

4
3 2
4 2
7 3
8 3

Output示例

B
A
A
B

题解:

Python:

/*
BASH博弈:
    当n%(m+1)==0时,先手必败态
    否则必胜态
    
    n = k*(m+1) + r , 先手每次取走r,保持必胜态

*/
if __name__=='__main__':
    n = int(input())
    for i in range(1,n+1):
        a = input().split(' ')
        if int(a[0])%(int(a[1])+1)==0 :
            print('B')
        else:
            print('A')

1069 Nim游戏 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

有N堆石子。A B两个人轮流拿,A先拿。每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N及每堆石子的数量,问最后谁能赢得比赛。

例如:3堆石子,每堆1颗。A拿1颗,B拿1颗,此时还剩1堆,所以A可以拿到最后1颗石子。

Input

第1行:一个数N,表示有N堆石子。(1 <= N <= 1000)
第2 - N + 1行:N堆石子的数量。(1 <= A[i] <= 10^9)

Output

如果A获胜输出A,如果B获胜输出B。

Input示例

3
1
1
1

Output示例

A

题解:

Python:

/*
NIM博弈:
    每一堆石头数异或,结果为0 , 则先手必败,否则,先手必胜

*/

if __name__=='__main__':
    n = int(input())
    a = []
    for i in range(1,n+1):
        a.append(int(input()))
    x = a[0]
    for i in range(1,n):
        x ^= a[i]
    if x==0:
        print('B')
    else:
        print('A')
        

 

1072 威佐夫游戏 

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

有2堆石子。A B两个人轮流拿,A先拿。每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取。拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出2堆石子的数量,问最后谁能赢得比赛。

例如:2堆石子分别为3颗和5颗。那么不论A怎样拿,B都有对应的方法拿到最后1颗。

Input

第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
第2 - T + 1行:每行2个数分别是2堆石子的数量,中间用空格分隔。(1 <= N <= 2000000)

Output

共T行,如果A获胜输出A,如果B获胜输出B。

Input示例

3
3 5
3 4
1 9

Output示例

B
A
A

题解:

C++:

/*
题意:给两堆石头,每次从任意一堆或者从两堆中同时拿去K个石子,问最后一个取走石子的获胜。
思路:板题
      x,y的最小值 = fabs(x-y)*(sqrt(5)+1)/2.0
      后手胜,否则,先手胜

*/

#include<bits/stdc++.h>

using namespace std;

int main(){
    int n,x,y;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>x>>y;
        int g = fabs(x-y)*(sqrt(5)+1)/2.0;
        int z = min(x,y);
        g==z?cout<<"B"<<endl:cout<<"A"<<endl;
    }
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值