5-4周练博客

A

大数加法

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

Input

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

Output

输出A + B

Sample Input

68932147586

468711654886

Sample Output

537643802472

很简单的一道高精度,不过,挺考验人的耐心

一个大数加法,一个大数减法,然后判断AB的正负,总共4种情况

AB正——直接输出

AB负——输出负的(|A|+|B|

AB负——输出A-B

AB正——输出B-A

代码:

#include<iostream>

using namespace std;

#include<string>

#include<cstring>

#include<cmath>

#include<algorithm>

#define M 20000

int pd(char a[],char b[])

{

       inti,j;

   int len1=strlen(a);

   int len2=strlen(b);

  //cout<<len1<<" "<<len2<<endl;

   if (len1>len2) return 1;

   if (len1<len2) return 0;

   for (i=0;i<=len1;i++)

    {

           if (a[i]<b[i])

           {

   //     cout<<"\t"<<a[i]<<""<<b[i]<<endl;

           return 0;

           }

           if (a[i]>b[i])

           {

                  return 1;

              }

       }

       return1;

}

void xf(char s1[],char s2[])

{

       inti,j;

       intt=0;

       intc1=0,c2=0;

       intl1=strlen(s1),l2=strlen(s2);

       if(s1[0]=='-') c1++;

       if(s2[0]=='-') c2++;

       for(i=c1;i<l1;i++)

       {

              if(s1[i]=='0') {

              t++;continue;}

              break;

       }

       if(t==l1) {

              s1[0]=48;s1[1]=0;

       }

       if(t>0)

       for(i=c1;i<=l1-t;i++)

       s1[i]=s1[i+t];

       t=0;

       for(i=c2;i<l2;i++)

       {

              if(s2[i]=='0') {

              t++;continue;}

              break;

       }

       if(t>0)

       for(i=c2;i<=l2-t;i++)

       s2[i]=s2[i+t];

       if(t==l2) {

              s2[0]=48;s2[1]=0;

       }

}

void xf2(char s1[])

{

       inti,j;

       intt=0;

       intc1=0;

       intl1=strlen(s1);

       if(s1[0]=='-') c1++;

       for(i=c1;i<l1;i++)

       {

              if(s1[i]=='0') {

              t++;continue;}

              break;

       }

       if(t==l1) {

              s1[0]=48;s1[1]=0;

       }

       if(t>0)

       for(i=c1;i<=l1-t;i++)

       s1[i]=s1[i+t];

}

int num1[M],num2[M];

void jian(char s1[],char s2[],char t[])

{

    int i,j;

    int len1=strlen(s1);

    int len2=strlen(s2);

    int a=max(len1,len2);

    for (i=0;i<=a+3;i++)

    num1[i]=num2[i]=0;

    for(i=len1-1,j=0;i>=0;i--)

            num1[j++]=s1[i]-'0';

    for(i=len2-1,j=0;i>=0;i--)

            num2[j++]=s2[i]-'0';

    for (i=0;i<a;i++)

    {

          num1[i]=num1[i]-num2[i];

          if (num1[i]<0)

          {

                 num1[i]=10+num1[i];

                 num1[i+1]--;

              }

       //     cout<<num1[i];

        }

        i=a-1;

        while(i>=0&&num1[i]==0) i--;

        if (i<0)

        {

             t[0]='0';t[1]=0;

             return;

        }

        a=i+1;

        for (i=0;i<a;i++)

    {

          t[i]=num1[a-1-i]+48;

          //cout<<t[i];

           //cout<<t[i]<<""<<num1[a-1-i]<<" "<<i<<endl;

        }

        t[a]=0;

}

void Add(char s1[],char s2[],char t[])

 {

    int num1[M],num2[M];

    int i,j;

    int len1=strlen(s1);

    int len2=strlen(s2);

    int a=max(len1,len2);

    for (i=0;i<=a+3;i++)

    num1[i]=num2[i]=0;

    for(i=len1-1,j=0;i>=0;i--)

            num1[j++]=s1[i]-'0';

    for(i=len2-1,j=0;i>=0;i--)

            num2[j++]=s2[i]-'0';

    for(i=0;i<a;i++)

    {

        num1[i]+=num2[i];

        if(num1[i]>9)

        {

            num1[i]-=10;

            num1[i+1]++;

        }

    }

    if (num1[i]>0) a++;

    for (i=0;i<a;i++)

     {

          t[i]=num1[a-1-i]+48;

           //cout<<t[i]<<""<<num1[a-1-i]<<" "<<i<<endl;

        }

        t[a]=0;

       //cout<<endl;

}

char c[11000],a[11000],b[11000];

int main()

{

       cin>>a>>b;

       xf(a,b);

       if(a[0]=='-'&&b[0]=='-')

       {

              intl1=strlen(a),l2=strlen(b);

              Add(a+1,b+1,c);

                     intl=strlen(c);

              if(c[0]=='0'&&strlen(c)==1||strlen(c)==0)

              {

              cout<<"-";

              intj;

       for(j=0;j<l;j++)

       {

              if(c[j]!='0') break;

       }

       if(j==l) j=0;

              cout<<0;

                     return0;

              }

              cout<<"-";

              intj;

       for(j=0;j<l;j++)

       {

              if(c[j]!='0') break;

       }

       if(j==l) j=0;

              for(int i=0;i<l;i++)

              cout<<c[i];

              return0;

       }

       if(a[0]=='-'&&b[0]!='-')

       {

              intl1=strlen(a);

              intl2=strlen(b);

              //cout<<l1<<""<<l2<<endl;

              intt=pd(b,a+1);

       //     cout<<"sda"<<t<<endl;

              if(t)

              {

                     jian(b,a+1,c);

                     int l=strlen(c);

                     intj;

       for(j=0;j<l;j++)

       {

              if(c[j]!='0') break;

       }

       if(j==l) j=0;

                     for(int i=0;i<l;i++)

                     cout<<c[i];

                     return0;

              }

              jian(a+1,b,c);

                     intl=strlen(c);

                     cout<<"-";

                     intj;

       for(j=0;j<l;j++)

       {

              if(c[j]!='0') break;

       }

       if(j==l) j=0;

                     for(int i=0;i<l;i++)

                     cout<<c[i];

                     return0;

       }

       //jian(a,b,c);

       if(a[0]!='-'&&b[0]=='-')

       {

              intl1=strlen(b);

              intt=pd(a,b+1);

       //     cout<<t<<"sadas"<<endl;

              if(t)

              {

                     jian(a,b+1,c);

                     intl=strlen(c);

                     intj;

       for(j=0;j<l;j++)

       {

              if(c[j]!='0') break;

       }

       if(j==l) j=0;

                     for(int i=0;i<l;i++)

                     cout<<c[i];

                     return0;

              }

              jian(b+1,a,c);

                     intl=strlen(c);

                     cout<<"-";

                     intj;

       for(j=0;j<l;j++)

       {

              if(c[j]!='0') break;

       }

       if(j==l) j=0;

                     for(int i=0;i<l;i++)

                     cout<<c[i];

                     return0;

       }

       Add(a,b,c);    

       intl=strlen(c);

       intj;

       for(j=0;j<l;j++)

       {

              if(c[j]!='0') break;

       }

       if(j==l) j=0;

       for(int i=j;i<l;i++)

       cout<<c[i];

       return0;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

BBash游戏

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

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

Input

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

Output

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

Sample Input

4

3 2

4 2

7 3

8 3

Sample Output

B

A

A

B

题解:

纯粹考验智商,如果(K+1| N那么B赢,否则A

证明——脑子是个好东西,然鹅我并没有,看别的博客吧。。。。。。。

代码:

#include<cstdio>

#include<iostream>

using namespace std;

int deal()

{

         int n,k;

         cin>>n>>k;

         if(n<=k)

         {

                 cout<<"A\n";

                 return 0;

         }

         if(n%(k+1)==0)

         {

                 cout<<"B\n";

                 return 0;

         }

         else{

                 cout<<"A\n";

                 return 0;

         }

        

}

int main()

{

         int t;

         cin>>t;

         while(t--)

         deal();

}

    C - 逆序数

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

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

Input

1行:NN为序列的长度(n <= 50000)
2 - N + 1行:序列中的元素(0 <= Aii <= 10^9

Output

输出逆序数

Sample Input

4

2

4

3

1

Sample Output

4

题解:

归并排序输出逆序数

代码:

#include<iostream>

using namespace std;

#include<cmath>

int a[1000000],b[1000000];

int ans=0;

void merge(int a[],int b[],int l,int r,intrend)

{

         int t=l;

         intpl=l,pr=r;

         intmid=r-1;

         intne=abs(l-rend)+1;

//       for(inti=l;i<=rend;i++)

         //cout<<a[i]<<"";

//       cout<<endl;

         while(pl<=mid&&pr<=rend)

         {

                 if(a[pl]<=a[pr])

                 {

                          b[t++]=a[pl++];

                 }

                 else

                 {

                          b[t++]=a[pr++];

                 //       cout<<"\t\t"<<b[t-1]<<""<<mid-pl+1<<endl;

                          ans+=mid-pl+1;

                 }

         }

         while(pl<=mid){

         b[t++]=a[pl++];}

         while(pr<=rend){

         b[t++]=a[pr++];}

         for (int i=0;i<ne;i++,rend--)

         {

                 a[rend]=b[rend];

         }

}

int mergesort(int a[],int b[],int l,int r)

{

         if(l<r)

         {

         intmid=(l+r)/2;

//       cout<<l<<""<<r<<endl;

         mergesort(a,b,l,mid);

         mergesort(a,b,mid+1,r);

//       cout<<"\tmerge:"<<l<<""<<mid+1<<" "<<r<<endl;

         merge(a,b,l,mid+1,r);

         }

}

int main()

{

         int n;

         cin>>n;

         int i;

         for (i=0;i<n;i++)

         cin>>a[i];

         mergesort(a,b,0,n-1);

         cout<<ans;

}

 

 

D - N的阶乘的长度

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

Input

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

Output

输出N的阶乘的长度

Sample Input

6

Sample Output

3

题解:

n=n*(n-1)*(n-2)*…*2*1

f(n)表示n的位数

f(n)=lgn+1;

f(n)=lg(n*(n-1)*(n-2)*…*2*1)=lg(n)+lg(n-1)+…+lg(2)+lg(1)+1;

代码:

#include<iostream>
using namespace std;
#include<cmath>
int main()
{
         int n;
         cin>>n;
         long long ans;
         double s=1;
         for (int i=1;i<=n;i++)
         {
                 s+=log10(i);
         }
         ans=s;
         cout<<ans;

 }

 

E - 机器人走方格

M * N的方格,一个机器人从左上走到右下,只能向右或向下走。有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果。

Input

1行,2个数M,N,中间用空格隔开。(2 <= m,n <= 1000)

Output

输出走法的数量。

Sample Input

2 3

Sample Output

3

 

题解:

记忆化搜索

f[i][j]表示以ij为终点的方法数

因为机器人只能往下走或者往右走所以:

f[i][j]=f[i-1][j]+f[i][j-1]

初始化;f[1][1]=1;

代码:

#include<iostream>

using namespace std;

const int mod=1000000007;

int f[1010][1010],v[1010][1010];

int dfs(int x,int y)

{

         if(x<=0||y<=0) return 0;

         if (x==1&&y==1) return 1;

         if(v[x][y]) return f[x][y];

         int ans;

         v[x][y]=1;

         ans=(dfs(x-1,y)%mod+dfs(x,y-1)%mod)%mod;

         f[x][y]=ans;

         return ans;

}

int main()

{

         int m,n;

         cin>>m>>n;

         cout<<dfs(m,n)<<endl;

}

 

 

F - 编辑距离

编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。

例如将kitten一字转成sitting

sitten k->s

sittin e->i

sitting ->g

所以kittensitting的编辑距离是3。俄罗斯科学家Vladimir Levenshtein1965年提出这个概念。

给出两个字符串a,b,求ab的编辑距离。

Input

1行:字符串a(a的长度 <= 1000)
2行:字符串b(b的长度 <= 1000)

Output

输出ab的编辑距离

Sample Input

kitten

sitting

Sample Output

3

题解:

f[i][j]为以字符串ai个位置与字符串bj个位置为终点,需要更改的最小次数

所以就很容易想到状态转移方程:

f[i][j]=min(f[i-1][j]+1,f[i][j-1]+1,f[i-1][j-1]+t);

如果a[i]==a[j]的话t=0否则t=1;

坑点:

初始化

i=1…strlen(A)

f[i][0]=i

J=1…STRLEN(B)

f[0][j]=j

代码:

#include<iostream>

using namespace std;

#include<string>

#include<cmath>

string a,b;

int f[2000][2000],v[2000][2000];

int main()

{

         cin>>a>>b;

         intl1=a.length(),l2=b.length();

         int i,j;

         for (i=0;i<=l1+1;i++)

         {

                 f[i][0]=i;

                 v[i][0]=1;

          }

          for (i=0;i<=l2+1;i++)

         {

                 f[0][i]=i;

                 v[0][i]=1;

          }

         for (int i=1;i<=l1;i++)

         for (int j=1;j<=l2;j++)

         {

                 intcost;

                 cost=(a[i-1]==b[j-1])?0:1;

                 f[i][j]=min(min(f[i-1][j]+1,f[i][j-1]+1),f[i-1][j-1]+cost);

         }

         cout<<f[l1][l2];

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值