2020 ICPC Asia Taipei-Hsinchu Regional C - Pyramid (思维)

2020 ICPC Asia Taipei-Hsinchu Regional C - Pyramid (思维)_第1张图片
题意:一个倒三角金字塔的每个节点上都有一个开关,然后开关初始状态都是向左打开,每次当小球经过一个节点时,该节点的开关状态就会改变,从左变为右,或者从右变为左。然后问你第K次放置的小球会从哪个出口离开,对角线线上的点就是出口的位置。

思路:思维的点就是,看上一层和下一层之间的节点状态变化关系,因为只有左右两种方向,那么对于某个节点,假如一个小球经过他x次,那么他左边的顶点就会经过(x+1)/2次,右边就是x/2次,这样我们就可以从开始的节点往下递推一下,得到整张图的某个节点经过的次数,它的第k次的节点状态也就得到了,再模拟一下小球的下落过程就可以了。

代码:

#include

using namespace std;
typedef long long ll;
const int MAXN = 1e4 + 7;
int mp[MAXN][MAXN];char check[MAXN][MAXN];
int n,k;

inline int read(){
	int X=0; bool flag=1; char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
	while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
	if(flag) return X;
	return ~(X-1);
}


inline int solve(int x,int y){
	if(x + y == n + 1) return y - 1;
	if(mp[x][y] == 1) solve(x + 1,y);
	else solve(x,y + 1);
}
inline void Clear(){
	for(int i = 1;i <= n;i ++)
		for(int j = 1;j + i <= n + 1;j ++) mp[i][j] = 0;
}

int main(){
	int T;
	T = read();
	while(T--){
		// scanf("%d%d",&n,&k);
		n = read(),k = read();
		Clear();
		mp[1][1] = k;//走了k次
		for(int i = 1;i <= n;i ++){
			for(int j = 1;j  + i <= n + 1;j ++){
				mp[i+1][j] += (mp[i][j] + 1) / 2;
				mp[i][j+1] += mp[i][j] / 2;
			}
		}
		for(int i = 1;i <= n;i ++){
			for(int j = 1;i + j <= n + 1;j ++){
				mp[i][j] = mp[i][j] & 1;
			}
		}
		printf("%d\n",solve(1,1));

		
	}
	return 0;
}

你可能感兴趣的:(#,DFS,思维,DP)