上海市计算机学会竞赛平台2024年5月月赛丙组棋盘问题(二)

题目描述

给定一个 𝑛∗𝑚n∗m 的棋盘,你需要在棋盘上放置黑白两个不同的皇后,请问有多少种放置方法能够使两个皇后之间互相不能攻击对方?

象棋中的皇后可以沿所在行、列及对角线移动任意距离。

输入格式

输入共一行,两个正整数 𝑛,𝑚n,m

输出格式

输出共一行,一个正整数表示答案

数据范围
  • 对于 30%30% 的数据,2≤𝑛,𝑚≤1022≤n,m≤102
  • 对于 60%60% 的数据,2≤𝑛,𝑚≤1042≤n,m≤104
  • 对于 100%100% 的数据,2≤𝑛,𝑚≤101002≤n,m≤10100
样例数据

输入:

4 3

输出:

40

详见代码:

#include <bits/stdc++.h>
using namespace std;
string n,m;
bool bj(string x,string y)
{
    int lenx=x.length();
    int leny=y.length();
    if (lenx>leny)
    {
        return true;
    }
  else if (lenx<leny)
    {
        return false;
    }
  else
    {
        for(int i=0;i<lenx;i++)
        {
            if (x[i]>y[i])
            {
                return true;
            }
          else if (x[i]<y[i]){
                return false;
            }
        }
    }
    return true;
}
string jia(string x,string y)
{
    string ret="";
    int yy=0;
    if (bj(x,y)==true)
    {
        swap(x,y);
    }
    int lenx=x.length();
    int leny=y.length();
    for(int i=lenx-1,j=leny-1;i>=0||j>=0;i--,j--)
    {
        if(i>=0)
        {
            yy+=x[i]-'0';
        }
        if (j>=0)
        {
            yy+=y[j]-'0';
        }
        ret=char(yy%10+'0')+ret;
        yy/=10;
    }
    if (yy>0)
    {
        ret=char(yy+'0')+ret;
    }
    return ret;
}
string cheng(string x,string y)
{
    int lenx=x.length();
    int leny=y.length();
    string ret="";
    vector <int> a(lenx+leny+2,0);
    for(int i=lenx-1;i>=0;i--)
    {
        for(int j=leny-1;j>=0;j--)
        {
            a[lenx-i+leny-j-1]+=(x[i]-'0')*(y[j]-'0');
        }
    }
    for(int i=1;i<=lenx+leny;i++)
    {
        a[i+1]+=a[i]/10;
        ret=char(a[i]%10+'0')+ret;
    }
    while(ret[0]=='0'&&ret.length()>1)
    {
        ret.erase(0,1);
    }
    return ret;
}
string jian(string x,string y)
{
    int lenx=x.length();
    int leny=y.length();
    int yy=0;
    string ret="";
    for(int i=lenx-1,j=leny-1;i>=0;i--,j--)
    {
        yy=x[i]-'0';
        if (j>=0)
        {
            yy-=y[j]-'0';
        }
        if (yy<0)
        {
            yy+=10;
            x[i-1]--;
        }
        ret=char(yy+'0')+ret;
    }
    while(ret[0]=='0'&&ret.length()>1)
    {
        ret.erase(0,1);
    }
    return ret;
}
string chu(string x,int y)
{
    int yy=0;
    string ret="";
    for(int i=0;i<x.length();i++)
    {
        yy=yy*10+x[i]-'0';
        ret+=char(yy/y+'0');
        yy%=y;
    }
    while(ret[0]=='0'&&ret.length()>1)
    {
        ret.erase(0,1);
    }
    return ret;
}
int main() 
{
    cin>>n>>m;
    if (bj(n,m)==true)
    {
        swap(n,m);
    }
    string t1=cheng(m,n);
    t1=cheng(t1,jian(t1,jian(jia(m,n),"1")));
    string t2=cheng("4",n);
    t2=cheng(t2,jian(n,"1"));
    t2=cheng(t2,jian(n,"2"));
    t2=chu(t2,3);
    string t3=jia(jian(m,n),"1");
    t3=cheng(t3,"2");
    t3=cheng(t3,n);
    t3=cheng(t3,jian(n,"1"));
    string ans=jian(jian(t1,t2),t3);
    cout<<ans;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值