题意:一个倒三角金字塔的每个节点上都有一个开关,然后开关初始状态都是向左打开,每次当小球经过一个节点时,该节点的开关状态就会改变,从左变为右,或者从右变为左。然后问你第K次放置的小球会从哪个出口离开,对角线线上的点就是出口的位置。
思路:思维的点就是,看上一层和下一层之间的节点状态变化关系,因为只有左右两种方向,那么对于某个节点,假如一个小球经过他x次,那么他左边的顶点就会经过(x+1)/2次,右边就是x/2次,这样我们就可以从开始的节点往下递推一下,得到整张图的某个节点经过的次数,它的第k次的节点状态也就得到了,再模拟一下小球的下落过程就可以了。
代码:
#include<bits/stdc++.h>
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;
}