Elementary Math Gym - 101485E(二分图匹配)

Elementary Math
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. Input The input consists of: • one line with one integer n (1 ≤ n ≤ 2 500), 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. 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.

题意:有n对数字,每对数字能通过加、减、乘得到三个结果,然后现在每对数选择一个结果,要让这n对数得到的结果都不同,判断是否存在。如果存在就输出这n个式子,不存在就输出impossible。

思路:二分图匹配,把每对数作为匹配的左端,把每对数的三种结果作为匹配的右端,进行匹配,如果最大匹配为n的话,就说明可以,然后判断一下是通过哪种运算得到的,输出式子,否则就是不行。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;

#define IOS                      \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0)
#define lowbit(a) (a & (-a))
#define ll long long
const ll llinf = 0x3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int maxn = 1e4 + 100;
const int minn = 1e3 + 10;
const double PI = acos(-1.0);
#define mod 1000000007
#define eps 1e-10

/*------------------------------------------------------*/

vector<ll> mp[maxn], kk;
map<ll, ll> match, vis, link;
ll x[maxn], y[maxn];
int n;

int dfs(ll u)
{
    for (int i = 0; i < mp[u].size(); i++)
    {
        ll v = mp[u][i];
        if (vis[v] == 0)
        {
            vis[v] = 1;
            if (match[v] == 0 || dfs(match[v]))
            {
                match[v] = u;
                link[u] = v;
                return 1;
            }
        }
    }
    return 0;
}

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld %lld", &x[i], &y[i]);
        mp[i].push_back(x[i] + y[i]);
        mp[i].push_back(x[i] - y[i]);
        mp[i].push_back(x[i] * y[i]);
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        vis.clear();
        if (dfs(i))
            ans++;
    }
    if (ans < n)
        printf("impossible\n");
    else
    {
        for (int i = 1; i <= n; i++)
        {
            if (x[i] + y[i] == link[i])
                printf("%lld + %lld = %lld\n", x[i], y[i], link[i]);
            else if (x[i] - y[i] == link[i])
                printf("%lld - %lld = %lld\n", x[i], y[i], link[i]);
            else if (x[i] * y[i] == link[i])
                printf("%lld * %lld = %lld\n", x[i], y[i], link[i]);
        }
    }
    return 0;
}
// 4
// 3 4
// 4 3
// 4 3
// 4 3
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值