uva 679 Dropping Balls(入门经典 例题6-6)
程序员文章站
2024-03-18 22:11:34
...
我刚看到题目想到的是模拟,但看到了12345个球的时候,就知道这个方法gg了,后来看了一下他的写发,我有了点感受:可以用结构体写的东西,需要用到指针表示的,都可以用数组写。这样写我感觉比指针写的可能更加好用一点。
这个是第一种超时的模拟做法,通过二叉树的性质:结点k的左右子节点编号分别位2k和2k+1。
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<set>
#include<stack>
#include<ctime>
#include<queue>
#define LOCAL
#define pi 3.1415926
#define e 2.718281828459
#define mst(a,b) memset(a,b,sizeof(a))
const int INF = 0x3f3f3f3f;
const int maxn = 30000;
using namespace std;
const int maxd = 20;
int s[1<<maxd]; //这样用位运算的方法表示2的次方,真的很好用
int main(){
int D,I;
int n;cin >> n;
while(n--){
while(scanf("%d%d",&D,&I) == 2){
mst(s,0);
int k , n = (1 << D) - 1;
for(int i = 0; i < I; i++){ //模拟小球下落的次数
k = 1;
for(;;){
s[k] = !s[k];
k = s[k] ? k * 2 : k * 2 + 1;
if(k > n )break;
}
}
cout << k/2 << endl;
}
}
return 0;
}
第二种:通过第几个小球判断,这个小球了落在了左子树还是右子树上,然后直接模拟最后一个小球的路线即可。
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<set>
#include<stack>
#include<ctime>
#include<queue>
#define LOCAL
#define pi 3.1415926
#define e 2.718281828459
#define mst(a,b) memset(a,b,sizeof(a))
const int INF = 0x3f3f3f3f;
const int maxn = 30000;
using namespace std;
int main(){
int n ;
cin >> n;
while(n--){
int D , I , k = 1;
while(scanf("%d%d",&D,&I) == 2){
int k = 1;
for(int i = 0; i < D - 1; i++)//模拟小球到达某一层的时候到了哪个结点
if(I % 2) {k = k * 2;I = (I+1) / 2;}
else {k = k * 2 + 1;I = I / 2;}
cout << k << endl;
}
}
return 0;
}
上一篇: 计蒜客 练习题 日期计算 date calculation
下一篇: UVa679 完全二叉树编号