B题分左边和右边的情况,以及特殊位置(1,-1),(1,1),(2,0)的情况特殊处理就好

#include<bits/stdc++.h>

using namespace std;
map<int, int> mp;//记录该列的火位置
int main() {
	int T;
	cin >> T;
	int n,r,c;
	while (T--) {
		int max_L = 0, max_R = 0, col;//左边和右边火
		bool flag = false;
		bool flag1 = 0, flag2 = 0;//(1,-1),(1,1)
		mp.clear();//
		cin >> n;
		//特殊情况为3		
		if (n == 0) {
			cout << 3 << endl;	continue;
		}

		for (int i = 0; i < n; ++i) {
			cin >> r >> c;
            //记录特殊的位置
			if (r == 1 && c == -1)	flag1 = 1;
			if (r == 1 && c == 1)  flag2 = 1;
			if (mp.find(c)!=mp.end())	mp[c] = 3;//火满(同1列2行都有)则记录为3
			else mp[c] = r;
		}		
		for (auto it = mp.begin(); it != mp.end(); ++it) {
			col = it->first;	
			int line = it->second;
			//鸡的右边
            if (col > 0) {
            //间隔-1或1或0有火,  
            	//间隔0,即位于同一列
				if (mp[col] == 3)
					max_R = 2;
                //间隔1或-1
				else if ((mp.find(col + 1) != mp.end() && mp[col + 1] != line) ||
					(mp.find(col - 1) != mp.end() && mp[col - 1] != line))
					max_R = 2;				
				//其他情况,有火的直接存下来就好
                else 
					max_R = max(max_R, 1);
												
			}
			//鸡的左边
			else if (col < 0) {				
				if (mp[col] == 3)
					max_L = 2;
				else if ((mp.find(col + 1) != mp.end() && mp[col + 1] != line) ||
					(mp.find(col - 1) != mp.end() && mp[col - 1] != line))
					max_L = 2;
				else
					max_L = max(max_L, 1);
			}	
			//鸡的下面(2,0)
			else flag = true;
		}
		if (flag) {
			if (flag1) max_L = 2;
			else max_L = max(max_L,1);
			if (flag2)	max_R = 2;
			else max_R = max(max_R,1);
		}
		int ans = 4 - max_L - max_R;
		//围绕鸡有3个特殊位置
		if (flag1)	ans = min(ans, 2);
		if (flag2)	ans = min(ans, 2);
        if(flag1&&flag2)  ans=min(ans,1);
		cout << ans <<endl;
	}
	return 0;
}