bzoj4429: [Nwerc2015] Elementary Math小学数学

4429: [Nwerc2015] Elementary Math小学数学

Description

Ellen is teaching elementary math to her students and the time for the final exam has come. The exam consists of n questions. In each question the students have to add (+), subtract (−) or multiply (∗) a pair of numbers.
Ellen has already chosen the n pairs of numbers. All that remains is to decide for each pair which of the three possible operations the students should perform. To avoid students getting bored, Ellen wants to make sure that the n correct answers to her exam are all different.
Please help Ellen finish constructing the exam by automating this task.
Ellen给她的学生教小学数学。期末考试已经来临了。考试有n个题目,每一个题目学生们都要对一对数字进行加(+),减(-),乘(*)运算。
Ellen已经选好了n对数。剩下的是决定学生们应该对每对数执行什么运算。为了不让学生们感到厌烦,Ellen想确保n个正确答案都不一样。
请帮助Ellen自动化地构建考试。

Input

The input consists of:
one line with one integer n (1≤n≤2500), the number of pairs of numbers;
n lines each with two integers a and b (−10^6≤a,b≤10^6), a pair of numbers used.
输入包括:
第一行是一个整数n(1<=n<=2500),表示共有n道题目。
接下来n行每行有2个整数a和b(-10^6<=a,b<=10^6),表示每一题使用的整数。

Output

For each pair of numbers (a,b) in the same order as in the input, output a line containing a valid equation. Each equation should consist of five parts: a, one of the three operators, b, an equals sign (=), and the result of the expression. All the n expression results must be different.
If there are multiple valid answers you may output any of them. If there is no valid answer, output a single line with the string “impossible” instead.
对于输入中的每一对(a,b),输出一行有效的方程。每一个方程应该包含5部分:a,+、-、*中的一个运算符,b,=,答案。N个答案必须不同。
如果有多个有效答案,你可以输出任意一个。如果没有答案,输出“impossible”。

Sample Input

Sample input 1
4
1 5
3 3
4 5
-1 -6
Sample input 2
4
-4 2
-4 2
-4 2
-4 2

Sample Output

Sample output 1
1 + 5 = 6
3 * 3 = 9
4 - 5 = -1
-1 - -6 = 5

Sample output 2
impossible


好久没搞题了……avl树还是搞不懂……

二分图匹配……继续练一下这个qwq一边的点为一组数a,b;一边为所有可能得到的结果,统计一下,匹配即可。

注意long long

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
#define Max 1e9
long long n,gs=0,dis=1e9,ans=0;
long long a[3000],b[3000],vis[100005],sv[3000][2];
long long sum[100005],dx[3000],dy[100005],cx[3000],cy[100005];
map<long long,int> pd;
int bfs()
{
    queue<long long> q;
    dis=Max;
    memset(dx,0,sizeof(dx));
    memset(dy,0,sizeof(dy));
    for (int i=1;i<=n;i++)
    {
        if (!cx[i]) q.push(i);
    }
    while (!q.empty())
    {
        long long x=q.front();
        q.pop();
        if (dx[x]>dis) break;
        for (int i=1;i<=gs;i++)
        {
            if (!dy[i]&&(a[x]+b[x]==sum[i]||a[x]-b[x]==sum[i]||a[x]*b[x]==sum[i]))
            {
                dy[i]=dx[x]+1;
                if (!cy[i]) dis=dy[i];
                else
                {
                    dx[cy[i]]=dy[i]+1;
                    q.push(cy[i]);
                }
            }
        }
    }
    return dis!=Max;
}
int find(long long x)
{
    for (int i=1;i<=gs;i++)
    {
        if (!vis[i]&&(a[x]+b[x]==sum[i]||a[x]-b[x]==sum[i]||a[x]*b[x]==sum[i])&&dy[i]==dx[x]+1)
        {
            vis[i]=1;
            if (cy[i]&&dy[i]==dis) continue;
            if (!cy[i]||find(cy[i]))
            {
                cx[x]=i;cy[i]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    scanf("%lld",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&a[i],&b[i]);
        long long x=a[i]+b[i];
        if (!pd[x])
        sum[++gs]=x,pd[x]=1;
        x=a[i]-b[i];
        if (!pd[x])
        sum[++gs]=x,pd[x]=1;
        x=a[i]*b[i];
        if (!pd[x])
        sum[++gs]=x,pd[x]=1;
    }
    while (bfs())
    {
        memset(vis,0,sizeof(vis));
        for (int i=1;i<=n;i++)
        {
            if (!cx[i])
            {
                ans+=find(i);
            }
        }
    }
    if (ans!=n)
    {printf("impossible");return 0;}
    else
    {
        for (int i=1;i<=n;i++)
        {
            if (a[i]+b[i]==sum[cx[i]])
            printf("%lld + %lld = %lld\n",a[i],b[i],sum[cx[i]]);
            else if (a[i]-b[i]==sum[cx[i]])
            printf("%lld - %lld = %lld\n",a[i],b[i],sum[cx[i]]);
            else if (a[i]*b[i]==sum[cx[i]])
            printf("%lld * %lld = %lld\n",a[i],b[i],sum[cx[i]]);
        }
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值