山东省第六届ACM大学生程序设计竞赛-Single Round Math(大数除法)

本文介绍了一种使用高精度运算解决特定情侣匹配问题的方法。该问题要求判断能否将给定数量的男士和女士分为11组,使得每组内都是一对情侣,并且没有剩余的人。通过自定义高精度加法、减法、乘法和除法实现了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Single Round Math

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

Association for Couples Math (ACM) is a non-profit organization which is engaged in helping single people to find his/her other half. As November 11th is “Single Day”, on this day, ACM invites a large group of singles to the party. People round together, chatting with others, and matching partners.
There are N gentlemen and M ladies in the party, each gentleman should only match with a lady and vice versa. To memorize the Singles Day, ACM decides to divides to divide people into 11 groups, each group should have the same amount of couples and no people are left without the groups.
Can ACM achieve the goal?
 

输入

 The first line of the input is a positive integer T. T is the number of test cases followed. Each test case contains two integer N and M (0 ≤ N, M ≤ 10 1000), which are the amount of gentlemen and ladies.

输出

 For each test case, output “YES” if it is possible to find a way, output “NO” if not.

示例输入

3
1 1
11 11
22 11

示例输出

NO
YES
NO

提示

 

来源

 

题目意思:

分别给出男和女的人数,是否能够分成11组,且每组男女两两一对,没有人是多余的。


解题思路:

高精度除法。

数据真是大得可怕…10的1000次方…

直接套用的kuangbin大神的模板~然后自己写了个判断两个数是否相等的函数。

注意以下三种情况不满足的话就是NO:

①男女必须两两配对人数要相同;
②男女人数要是11的倍数;
③不能有被剩下的人。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

//compare比较函数:相等返回0,大于返回1,小于返回-1
int compare(string str1,string str2)
{
    if(str1.length()>str2.length()) return 1;
    else if(str1.length()<str2.length())  return -1;
    else return str1.compare(str2);
}
//高精度加法
//只能是两个正数相加
string add(string str1,string str2)//高精度加法
{
    string str;
    int len1=str1.length();
    int len2=str2.length();
    //前面补0,弄成长度相同
    if(len1<len2)
    {
        for(int i=1; i<=len2-len1; i++)
            str1="0"+str1;
    }
    else
    {
        for(int i=1; i<=len1-len2; i++)
            str2="0"+str2;
    }
    len1=str1.length();
    int cf=0;
    int temp;
    for(int i=len1-1; i>=0; i--)
    {
        temp=str1[i]-'0'+str2[i]-'0'+cf;
        cf=temp/10;
        temp%=10;
        str=char(temp+'0')+str;
    }
    if(cf!=0)  str=char(cf+'0')+str;
    return str;
}
//高精度减法
//只能是两个正数相减,而且要大减小
string sub(string str1,string str2)//高精度减法
{
    string str;
    int tmp=str1.length()-str2.length();
    int cf=0;
    for(int i=str2.length()-1; i>=0; i--)
    {
        if(str1[tmp+i]<str2[i]+cf)
        {
            str=char(str1[tmp+i]-str2[i]-cf+'0'+10)+str;
            cf=1;
        }
        else
        {
            str=char(str1[tmp+i]-str2[i]-cf+'0')+str;
            cf=0;
        }
    }
    for(int i=tmp-1; i>=0; i--)
    {
        if(str1[i]-cf>='0')
        {
            str=char(str1[i]-cf)+str;
            cf=0;
        }
        else
        {
            str=char(str1[i]-cf+10)+str;
            cf=1;
        }
    }
    str.erase(0,str.find_first_not_of('0'));//去除结果中多余的前导0
    return str;
}
//高精度乘法
//只能是两个正数相乘
string mul(string str1,string str2)
{
    string str;
    int len1=str1.length();
    int len2=str2.length();
    string tempstr;
    for(int i=len2-1; i>=0; i--)
    {
        tempstr="";
        int temp=str2[i]-'0';
        int t=0;
        int cf=0;
        if(temp!=0)
        {
            for(int j=1; j<=len2-1-i; j++)
                tempstr+="0";
            for(int j=len1-1; j>=0; j--)
            {
                t=(temp*(str1[j]-'0')+cf)%10;
                cf=(temp*(str1[j]-'0')+cf)/10;
                tempstr=char(t+'0')+tempstr;
            }
            if(cf!=0) tempstr=char(cf+'0')+tempstr;
        }
        str=add(str,tempstr);
    }
    str.erase(0,str.find_first_not_of('0'));
    return str;
}

//高精度除法
//两个正数相除,商为quotient,余数为residue
//需要高精度减法和乘法
void div(string str1,string str2,string "ient,string &residue)
{
    quotient=residue="";//清空
    if(str2=="0")//判断除数是否为0
    {
        quotient=residue="ERROR";
        return;
    }
    if(str1=="0")//判断被除数是否为0
    {
        quotient=residue="0";
        return;
    }
    int res=compare(str1,str2);
    if(res<0)
    {
        quotient="0";
        residue=str1;
        return;
    }
    else if(res==0)
    {
        quotient="1";
        residue="0";
        return;
    }
    else
    {
        int len1=str1.length();
        int len2=str2.length();
        string tempstr;
        tempstr.append(str1,0,len2-1);
        for(int i=len2-1; i<len1; i++)
        {
            tempstr=tempstr+str1[i];
            tempstr.erase(0,tempstr.find_first_not_of('0'));
            if(tempstr.empty())
                tempstr="0";
            for(char ch='9'; ch>='0'; ch--) //试商
            {
                string str,tmp;
                str=str+ch;
                tmp=mul(str2,str);
                if(compare(tmp,tempstr)<=0)//试商成功
                {
                    quotient=quotient+ch;
                    tempstr=sub(tempstr,tmp);
                    break;
                }
            }
        }
        residue=tempstr;
    }
    quotient.erase(0,quotient.find_first_not_of('0'));
    if(quotient.empty()) quotient="0";
}
int Equal(string str1,string str2)//判断两个数是否相等
{
    int i,flag=1;
    for(i=0; str1[i]!='\0'&&str2[i]!='\0'; ++i)
        if(str1[i]!=str2[i])
        {
            flag=0;
            break;
        }
    return flag;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int t;
    cin>>t;
    while(t--)
    {
        string n,m;
        string x1,y1,x2,y2;
        string q="11";
        string p="0";
        cin>>n>>m;
        //cout<<add(str1,str2)<<endl;
        //cout<<sub(str1,str2)<<endl;
        //cout<<mul(str1,str2)<<endl;
        if(!Equal(n,m))//男女生人数要相同
        {
            cout<<"NO"<<endl;
            continue;
        }
        div(n,q,x1,y1);
        if(!Equal(y1,p))//男女人数要是11的倍数
        {
            cout<<"NO"<<endl;
            continue;
        }
        div(m,q,x2,y2);
        if(!Equal(y2,p))
        {
            cout<<"NO"<<endl;
            continue;
        }
        if(!Equal(x1,x2))//不能有被剩下的人
        {
            cout<<"NO"<<endl;
            continue;
        }
        cout<<"YES"<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值