版权声明:本文为博主原创文章,若需转载请注明来源。若文章有错误or疏漏,欢迎私信指教~ https://blog.csdn.net/little_starfish/article/details/82492149
SDUT 第十届校赛H menhera酱那惨不忍睹的数学 (二分图匹配)
Input
第一行输入一个整数n,表示总的式子数。
接下来n行,每行两个数a,b分别表示每个式子的两个操作数。
1 <= n <= 100
1 <= b, a <= 100 且a,b都是整数
请注意输出格式,不得有多余空格,式子按照输入的顺序输出。
Output
如果存在一种上述合法的方案,第一行先输出”menhera”,然后输出任一 一种方案(格式见示例),否则输出”QAQ”,不包含引号。
Sample Input
3
1 3
2 4
5 7
Sample Output
menhera
1 + 3 = 4
2 + 4 = 6
5 + 7 = 12
Hint
要求N个答案不相同,除法运算是向下取整,即 5 / 2 = 2, 2 / 2 = 1
Source
豪子
思路
以为要求运算的答案只能出现一次,而四个运算可以任意一个,而数据范围又比较小,所以可以用二分图匹配(1<=N<=100,-99<=运算答案<=10000)
即将运算的式子与式子的运算答案寻找最大匹配,若匹配数==式子的数N,则有解,暴力循环输出答案即可,否则QAQ
AC代码
#include <bits/stdc++.h>
using namespace std;
int p[111][11111]; //存答案
bool used[11111]; //标记是否使用
int book[11111];
int x[111], y[111];
bool dfs(int k)
{
int i;
for(i = 1; i <= 10100; i++)
{
if(p[k][i]&&!used[i])
{
used[i] = 1;
if(book[i] == 0||dfs(book[i]))
{
book[i] = k;
//book[k] = i;
return true;
}
}
}
return false;
}
int main()
{
memset(p, 0, sizeof(p));
memset(book, 0, sizeof(book));
int a, b, c, d;
int i, j, n;
scanf("%d", &n);
for(i = 1; i <= n; i++){
scanf("%d %d", &x[i], &y[i]);
a = x[i] + y[i]; //将+ - * /四种运算的结果保存
b = x[i] - y[i];
c = x[i] * y[i];
d = x[i] / y[i];
p[i][a+100] = 1; //因为可能运算结果可能有负数,所以统一结果+100
p[i][b+100] = 1;
p[i][c+100] = 1;
p[i][d+100] = 1;
}
int sum = 0;
for(i = 1; i <= n; i++)
{
memset(used, 0, sizeof(used));
if(dfs(i))
sum++;
}
if(sum == n)
{
printf("menhera\n");
for(i = 1; i <= n; i++)
{
for(j = 1; j <= 10100; j++)
{
if(book[j] == i)
{
if(x[i]+y[i]==j-100)
printf("%d + %d = %d\n", x[i], y[i], j-100);
else if(x[i]-y[i]==j-100)
printf("%d - %d = %d\n", x[i], y[i], j-100);
else if(x[i]*y[i]==j-100)
printf("%d * %d = %d\n", x[i], y[i], j-100);
else
printf("%d / %d = %d\n", x[i], y[i], j-100);
break;
}
}
}
}
else
printf("QAQ\n");
return 0;
}