#include <cstdio>
#include <vector>
using namespace std;
const int N = 1024+5;
char table[N][N];
int main()
{
int n;
//freopen("in.txt","r",stdin);
while(scanf("%d",&n) == 1){
vector<int> win,lose;
for(int i = 1; i <= n; ++i) scanf("%s",table[i]+1);
for(int i = 2; i <= n; ++i){
if(table[1][i] == '1') win.push_back(i);
else lose.push_back(i);
}
int num = n;
while(num > 1){
vector<int> win2, lose2, final; // phase 3/4
// phase 1: 尽量让黑色和灰色配对
for(int i = 0; i < lose.size(); ++i){ // 枚举黑色
int tolose = lose[i];
bool matched = false;
for(int j = 0; j < win.size(); ++j){ // 找一个可以打败他的灰色
int& towin = win[j];
if(towin > 0 && table[towin][tolose] == '1'){
printf("%d %d\n",towin,tolose);
win2.push_back(towin); // 进入下一轮
towin = 0; //本轮比赛不能再用了
matched = true;
break;
}
}
if(!matched) final.push_back(tolose);//没有配对的黑色,加入final准备自相残杀
}
// phase 2: 给1号找一个可以打败的对手,剩下的加入final
bool first = true;
for(int i = 0; i < win.size(); ++i){
int towin = win[i];
if(towin > 0){
if(first) { printf("1 %d\n",towin); first = false; }
else final.push_back(towin);
}
}
// phase 3,4: 黑色任意配对,互相残杀;剩下的任意配对
for(int i = 0; i < final.size(); i += 2){
printf("%d %d\n",final[i],final[i+1]);
int keep = final[i];
if(table[final[i+1]][keep] == '1') keep = final[i+1];
if(table[1][keep] == '1') win2.push_back(keep);
else lose2.push_back(keep);
}
win = win2; lose = lose2;
num/= 2;
}
}
return 0;
}
代码是LRJ大佬的,真的强。