UVa679
这道题刚开始我的想法就是和书上那个超时的代码,一样的,通过一个树状数组去模拟那个过程和书上分析的那样,测试数据太过庞大,虽然没有数组移动这样耗时的程序,但for(int i=0;i<I;i++)中的for最多可以有524288
,而且还有一万组,肯定会超时。所以现在重点是如何减小对I的判断量,
模拟一个过程后,我们很容易发现到底某个点的球数Number,如果是奇数,
则最后一个往左边走,且左边比右边的球多一个,如果是偶数则往右边走,
且两边的数量一样多,然后按照书上那个优化算法写就可以了
,因为2^20约等于一百万>524288,所以for循环量被大大减小了。
UVa122
这道题非常好首先怎么输入就是个难点
因为这道题出现了跨行读取,就显得非常难处理了,仅仅通过while(scanf("%s",str)!=EOF这样没有办法判断每两次之间的分割符”()“,刘汝佳很巧妙的通过写一个read_input()函数来解决这个问题,因为while循环每次都要判断,所以读到()就返回true这样while还会继续,读到EOF返回false,程序结束。
正如刘汝嘉所说,大部分的ACM题并不需要内存池,但是学习这个可以锻炼工程思维,那段程序大致的作用是,首先声明一个足够大的数组,数组元素是Node,然后把他们的指针一一放到,一个队列中,每次需要新的节点时就从队首弹出来一个,如何回收那些用过的内存内,将remove_tree中的delete u;换成deletenode(u),就是把那些内存重新放入队尾
这道题需要判断什么样的二叉树是不正确的,有两种错误情况
1.有节点没有被赋值
2.有节点被重复赋值
设置一个全局变量failed都判断一下就行了
注意记住几个小技巧,strchr sscanf;
使用数组代替指针的方法与6.2最后一题思想类似。和结构体的区别就是他用四个数组来分别存放四个变量。
其实have_value这个变量不是必需的,只是有程序更健壮,用v这个值就可以判断了(再初期先全部赋值为0)
附上数组代码,其他两种代码仓库有
#pragma warning(disable:4996)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<queue>
#include<time.h>
using namespace std;
const int maxn = 256 + 10;
bool failed;
int cnt;
const int root = 1;
int left[maxn];
int right[maxn];
bool have_value[maxn];
int value[maxn];
void newtree()
{
left[root] = right[root] = 0;
have_value[root] = false;
cnt = root;
}
int newnode()
{
int u = ++cnt;
left[u] = right[u] = 0;
have_value[u] = false;
return u;
}
void addnode(int v, char* s) {
int n = strlen(s);
int u = root;
for (int i = 0; i < n; i++)
if (s[i] == 'L') {
if (left[u] == 0)left[u] = newnode();
u = left