J. Architect of Your Own Fortune
Vasya is a schoolboy who rides a trolley bus and then a bus to get to school. He’s
always very happy to get a “lucky ticket,” which means the total of the first three
digits in the ticket number equals the total of the last three digits. However, Vasya has
been down on his luck ever since the beginning of the new school year – over the past
month, he hardly had any lucky tickets at all.
Vasya thought this over and decided to take control of the situation. Upon reviewing
his recent tickets, he realized he can produce several lucky numbers by combining
trolley bus tickets with bus tickets. To that end, the schoolboy had to take two tickets,
fold them in half along the vertical axis and join halves of different tickets together.
The first three digits of the new “super lucky ticket” are the three digits on the lefthand
side of the ticket for one mode of transport, and the last three digits are the three
digits on the right-hand side of the ticket for the other mode of transport.
Example: let us assume that Vasya has a trolley bus ticket with the number 123456
and a bus ticket with the number 789222. They can be combined either as 123222 or
as 789456. The first one of these two combinations is super lucky.
Your task is to write a program that will help produce the maximum number of super
lucky combinations from the tickets available, assuming each ticket can only be used
in one combination.
Limitations
1 ≤ n, m ≤ 100.
Input
The first line of the input file contains two integer numbers n and m separated by a
space. The second line of the input file contains n six-digit integer numbers separated
by a space, representing numbers of bus tickets. The third line of the input file
contains m six-digit integer numbers separated by a space, representing numbers of
trolley bus tickets.
Output
The first line of the output file must contain integer number k – the maximum
possible number of super lucky combinations. The following k lines must contain
these super lucky combinations. Each line with a super lucky combination must start
with the Latin letters “AT” if the combination begins with numbers from a bus ticket
and ends with numbers from a trolley bus ticket; otherwise the line must start with the
letters “TA.” The letters must be followed by two six-digit numbers separated by a
space, representing the numbers of the relevant tickets.
12
12
2016-2017 ACM Central Region of Russia Quarterfinal Programming Contest
Examples
Input.txt Output.txt
2 2
123456 111222
141204 555000
2
TA 555000 123456
TA 141204 111222
题意:第一行输入n,m。第二行输入n组数属于A集合,第三行输入m组数属于T集合。若A集合中某组数的前3个数字的和(后3个数字的和)等于 T集合中某组数的后3个数字的和(前3个数字的和),就称这两组数能匹配。求最多有能匹配多少对(每组数只能使用一次)。先输出最多能匹配多少对,接着把每一对输出。若是A集合中某组数的前3个数字的和等于T集合中某组数的后3个数字的和,就输出:AT A中某组数 T中某组数;若是T集合中的前3个某组数前3个数字的和等于A集合中某组数的后3个数字的和,就输出:TA T中某组数 A中某组数。例如:A集合中的1111222后3个数字的和(6) 等于 T集合中的141204前3个数字的和(6),就输出 TA 141204 111222。
解题思路:二分图匹配。先把能匹配的用数组line[i][j]记录。line[i][j] = 1,表示A集合中的第i组数能与T集合中第j组数能匹配。at[i][j] 表示是A集合中某组数的前3个数字的和等于T集合中某组数的后3个数字的和,ta[i][j] 表示T集合中的前3个某组数前3个数字的和等于A集合中某组数的后3个数字的和。
#include
#include
#include
#include
#include
#include
using namespace std;
int n,m,all;
paira[105];
pairt[105];
int at[105][105],ta[105][105],line[205][205];
int used[105],tt[105];
char sa[105][10],st[105][10];
void Init(){
memset(line,0,sizeof(line));
memset(at,0,sizeof(at));
memset(ta,0,sizeof(ta));
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
if(a[i].first == t[j].second){
line[i][j] = 1;
at[i][j] = 1;
}
if(a[i].second == t[j].first){
line[i][j] = 1;
ta[i][j] = 1;
}
}
}
}
bool find(int x){
for(int j = 1;j <= m;j++){
if(line[x][j] == true && used[j] == false){
used[j] = 1;
if(tt[j] == 0 || find(tt[j])){
tt[j] = x;
return true;
}
}
}
return false;
}
void Print(){
printf("%d\n",all);
for(int i = 1;i <= m;i++){
if(tt[i]){
int xx = tt[i];
if(at[xx][i] == 1){
printf("AT ");
printf("%s ",sa[xx] + 1);
printf("%s\n",st[i] + 1);
}
else if(ta[xx][i] == 1){
printf("TA ");
printf("%s ",st[i] + 1);
printf("%s\n",sa[xx] + 1);
}
}
}
}
int main(){
freopen("input.txt" , "r" , stdin);
freopen("output.txt" , "w" , stdout);
while(~scanf("%d %d",&n,&m)){
memset(a,0,sizeof(a));
memset(t,0,sizeof(t));
for(int i = 1;i <= n;i++){
scanf("%s",sa[i] + 1);
a[i].first = sa[i][1] - '0' + sa[i][2] - '0' + sa[i][3] - '0';
a[i].second = sa[i][4] - '0' + sa[i][5] - '0' + sa[i][6] - '0';
}
for(int i = 1;i <= m;i++){
scanf("%s",st[i] + 1);
t[i].first = st[i][1] - '0' + st[i][2] - '0' + st[i][3] - '0';
t[i].second = st[i][4] - '0' + st[i][5] - '0' + st[i][6] - '0';
}
Init();
memset(tt,0,sizeof(tt));
all = 0;
for(int i = 1;i <= n;i++){
memset(used,0,sizeof(used));
if (find(i)) all++;
}
Print();
}
}