列表

详情


NC227311. 糟糕的打谱员

描述

众所周知,围棋是一项黑白双方轮流行动的棋类游戏。在围棋中,还有打劫的概念,若一方落子在某一个劫争处,则另一方不能立刻也下在这个劫争处,而之后还是可以下的。现在,你是一场史诗级围棋对弈(史诗级体现在这场棋每一步都下在了劫争上)的记谱员,但熬夜到早上七点才睡的你状态不佳,胡乱记了许多东西。

为了假装你有出色的完成记谱工作,请从你记录的谱子中找到一个最长的合法行棋子序列。

一个合法行棋子序列需要满足:

1. 任意相邻的两步,玩家不同(一黑一白);

2. 任意相邻的两步,不能下在同一个劫争处。

子序列是指原序列中删除若干(可以不删)元素得到的新序列。

输入描述

第一行是整数,测试组数。

每组测试用例,第一行是整数,你记录的谱子长度。

接下来行,每行两个数,表示一步棋,下这步棋的人是c_i且下在了编号为a_i的劫争处。

输出描述

每个测试用例输出一个整数,表示最长的合法行棋子序列长度。

示例1

输入:

1
20
1 10
0 6
0 9
1 3
0 3
0 5
0 3
1 1
0 2
0 2
0 2
1 9
1 10
1 1
1 10
0 6
0 8
1 1
1 9
0 1

输出:

10

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 380ms, 内存消耗: 424K, 提交时间: 2021-09-19 15:57:01

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;

void solve(){
	scanf("%d",&n);
	int ans=0,f[2][12]={0};
	for(int i=1;i<=n;i++){
		int c,a;
		cin>>c>>a;
		for(int j=1;j<=10;j++){
			if(j!=a) f[c][a]=max(f[c][a],f[1-c][j]+1);
		}
		ans=max(ans,f[c][a]);
	}
	cout<<ans<<endl;
}

int main(){
	int t;
	cin>>t; 
	while(t--){
		solve();
	}
	return 0;
}

上一题