|
2009年8月20日
1 2 struct Node 3 { 4 int data; 5 struct Node *next; 6 }; 7 8 int InitLink(Node *h) 9 { 10 int i; 11 Node *p, *q; 12 p = new Node; 13 p = h; 14 for (i = 1; i <= 10; ++i) 15 { 16 q = new Node; 17 q ->data = i; 18 p ->next = q; 19 p = q; 20 } 21 p ->next = NULL; 22 return 0; 23 }; 24 25 int ReverseLink(Node *head) 26 { 27 Node *p, *q, *cur; 28 29 p = head ->next; 30 cur = q = p; 31 cur = cur ->next; 32 p = p ->next->next; 33 q->next = NULL; 34 35 while (p != NULL) 36 { 37 cur ->next = q; 38 q = cur; 39 cur = p; 40 p = p->next; 41 } 42 cur ->next = q; 43 head ->next = cur; 44 return 0; 45 } 46 47 int main() 48 { 49 Node *head; 50 head = new Node; 51 InitLink(head); 52 ReverseLink(head); 53 return 0; 54 }
2009年5月30日
Cube Stacking
Cube StackingFarmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start with N stacks, each containing a single cube. Farmer John asks Betsy to perform P (1<= P <= 100,000) operation. There are two types of operations: moves and counts. * In a move operation, Farmer John asks Bessie to move the stack containing cube X on top of the stack containing cube Y. * In a count operation, Farmer John asks Bessie to count the number of cubes on the stack with cube X that are under the cube X and report that value. Write a program that can verify the results of the game.
------------------- 仍然是并查,仍然是想了很久,仍然是参考了别人的代码才明白,学了这么久,真的会怀疑自己的智商了。 PKU1988仍然是并查的题目,没有特意说要找并查的题目来做,只是偶尔到了某一页发现某一道题目可以用并查来做,于是载下去了。 题意: 其实题意比较好理解,两个命令:如果是c命令则算出输出的cube X下面有多少个立方体,如果是M命令,则把cube Y所在的集合中的全部立方体放入cube X 所在的立方集合下。 初始化: 定义一个结构体,保存一个cube的根cube存于parent中,保存cube上面的立方数于up中,保存cube的下面的立方数于down中。
struct node
  {
int parent;
int up;
int down;
}Node[SIZE];

void Init(int nt)
  {
for (int i=0; i <= nt;i++)
 {
Node[i].parent=i; //根为自己
Node[i].down=1; //初始化设为1只是为了计算的方便,到后面会减1
Node[i].up=0; //初始化高上面没有立方体。
}
}
合并操作: 合并的时候找两个cube的根结点,并且对要结点的up及dow变量进行操作。具体看代码注释
int UnionSet(int i,int j)
  {
i=FindSet(i);
j=FindSet(j);
Node[j].up=Node[i].down; //i下面的cube都变成了j上面的cube,归入Node[j].up
Node[i].down+=Node[j].down; //能够想像,j下面的所有cube同时也都归入i中
Node[j].parent=i; //两个集合合并成一个集合 i为根
return 0;
}
查询操作: 查询的时候找结点父亲,并且找父亲结点的上面cube数归入结点上面cube数中,如果父亲结点有根结点,则继续查找(哇,很难表达啊)。
int FindSet(int i)
  {
int m;
if (Node[i].parent!=i)
 {
m=Node[i].parent;
Node[i].parent=FindSet(Node[i].parent); //找父亲结点的父亲结点
Node[i].up+=Node[m].up; //将父亲结点的up归入结点的up中
}
return Node[i].parent;
}
主函数:
int main(int argc, char* argv[])
  {
// freopen("in.txt","r",stdin);
int p;
scanf("%d",&p);
char op;
Init(SIZE);
while(p--)
 {
getchar();
op=getchar();
if(op=='M')
 {
int x,y;
scanf("%d %d",&x,&y);
UnionSet(x,y);
}
else if(op=='C')
 {
int x,y;
scanf("%d",&x);
y=FindSet(x);
printf("%d\n",Node[y].down-Node[x].up-1); //这里需要减1
}
}
return 0;
}

2009年5月26日
A Simple Problem with Integers
Description
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval. ...............
一道简单的线段树题目,但是因为数据量大(1000000000 ≤ Ai ≤ 1000000000),按照常规的解法必然会超时,这里需要增加一些变量保存区间内的改变量.
结点定义: 这里结点有五个变量,分别是左子树,右子树,区间的初始值。对区间整体的改变值。该区间及子区间改变值
struct node
  {
int l; //左子树
int r; //右子树
__int64 value; //区间的初始量
__int64 tsum; //对区间的整体改变量
__int64 adt; //对区间及子区间的改变值
}Node[400040];
初始化: 建树的时候,每个结点保存这个结点跟其子树的结点值总和。
int build(int a,int b,int s)
  {
Node[s].l=a;
Node[s].r=b;
if(a==b)
 {
Node[s].value=v[a];
return 0;
}
else
 {
int mid=(a+b)/2;
build(a,mid,s*2);
build(mid+1,b,s*2+1);
Node[s].value=Node[s*2].value+Node[s*2+1].value;
return 0;
}
}
更新: 更新的时候,tsum记录整个区间的改变量。
int Modify(int a,int b,int s)
  {
Node[s].tsum+=(b-a+1)*mValue;
if(Node[s].l==a && Node[s].r==b)
 {
Node[s].adt+=mValue;
}
else
 {
int mid=(Node[s].l+Node[s].r)>>1;
if(b<=mid)
 {
Modify(a,b,s*2);
}
else if(a>mid)
 {
Modify(a,b,s*2+1);
}
else
 {
Modify(a,mid,s*2);
Modify(mid+1,b,s*2+1);
}
// Node[s].value=Node[s*2].value+Node[s*2+1].value;
}
return 0;
}
查询:
__int64 Query(int a,int b,int s)
  {
__int64 cost=0;
if(Node[s].l==a && Node[s].r==b)
 {
cost += Node[s].value + Node[s].tsum;
}
else
 {
cost+=(b-a+1)*Node[s].adt;
int mid=(Node[s].l+Node[s].r)>>1;
if(b<=mid)
 {
cost+=Query(a,b,s*2);
}
else if(a>mid)
 {
cost+=Query(a,b,s*2+1);
}
else
 {
cost+=Query(a,mid,s*2);
cost+=Query(mid+1,b,s*2+1);
}
}
return cost;
}
2009年5月22日
|