CS106B Section Solutions #4

Problem 1: Filling a Region

回溯思想填空白

#include <iostream>
#include "vector.h"
#include "grid.h"
using namespace std;

enum pixelStateT { White, Black };
struct pointT {
    int row, col;
};

void FillReign(pointT pt, Grid<pixelStateT> & screen);
bool IsOffGrid(pointT pt, Grid<pixelStateT> & grid);
pointT move(pointT pt, int i);

int main() {
    //创建图
    Grid<pixelStateT> screen(10,10);
    for(int i=0;i<10; i++) screen(0,i) = Black;
    for(int i=0;i<10; i++) screen(1,i) = White;
    for(int i=0;i<10; i++) screen(2,i) = Black;
    for(int i=0;i<10; i++) screen(3,i) = White;
    for(int i=0;i<10; i++) screen(4,i) = Black;
    for(int i=0;i<10; i++) screen(5,i) = White;
    for(int i=0;i<10; i++) screen(6,i) = Black;
    for(int i=0;i<10; i++) screen(7,i) = White;
    for(int i=0;i<10; i++) screen(8,i) = Black;
    for(int i=0;i<10; i++) screen(9,i) = White;

    //打印图
    for(int i=0; i<10; i++){
        cout<< screen(i,0)<<screen(i,1)<<screen(i,2)<<screen(i,3) <<screen(i,4)
            <<screen(i,5)<<screen(i,6)<<screen(i,7)<<screen(i,8)<<screen(i,9)<<endl;
        }
    //选择点
    cout <<"-------------"<<endl;
    pointT pt;
    pt.row = 7;
    pt.col = 4;
    //填充
    FillReign(pt, screen);
    //打印新图
    for(int j=0; j<10; j++){
        cout<< screen(j,0)<<screen(j,1)<<screen(j,2)<<screen(j,3) <<screen(j,4)
            <<screen(j,5)<<screen(j,6)<<screen(j,7)<<screen(j,8)<<screen(j,9)<<endl;
    }
    return 0;
}

void FillReign(pointT pt, Grid<pixelStateT> & screen){
    if (IsOffGrid(pt,screen))
        return;
    if (screen(pt.row, pt.col) == Black)
        return;
    screen(pt.row, pt.col) = Black;
    for(int i=0; i<4; i++) {
        FillReign(move(pt, i),screen);
    }
}

bool IsOffGrid(pointT pt, Grid<pixelStateT> & grid){
    return pt.row < 0 || pt.row >= grid.numRows() ||
           pt.col < 0 || pt.col >= grid.numCols();
}
pointT move(pointT pt, int i){
    pointT temp;
    switch(i){
        case 0: temp.row = pt.row-1; temp.col = pt.col ; break;
        case 1: temp.row = pt.row+1; temp.col = pt.col ; break;
        case 2: temp.row = pt.row; temp.col = pt.col-1 ; break;
        case 3: temp.row = pt.row; temp.col = pt.col+1 ; break;
    }
    return temp;


/*
结果展示:
point (7,4):
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
-------------
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
1111111111
1111111111
0000000000

point (8,4):
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
-------------
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000

*/

Problem 2: Shortest Path Through a Maze

由于mazesolve函数已经给出类,只需要稍微改改就行

int ShortestPathLength(pointT pt){
    int shortest, len;
    if(OutsideMaze(pt))
    {
        return 0;
    }
    if(IsMarked(pt))
    {
        return Nosolution;
    }
    shorest = NoSolution;
    MarkSquire(pt);
    for(directionT dir = North; dir <= West; dir = directionT(dir+1)){
        if(!WallExists(pt,dir))
        {
             len = ShortestPathLength(AdjacentPoint(pt, dir));
             if (len < shortest){
                 shortest = len;
                }
        }
    }
    UnmarkSquare(pt);
    if (shortest == NoSolution){
        return NoSolution;
        }
        else
        {
            return (shortest + 1);
            }
}

Problem 3: Pointers

这个指针概念问题没什么说得

Problem 4: Linked List Warmup

a) 两种方法将vector改成链表,递归方法看看就好

Cell * ConvertToListIter(Vector<int> vector){
    Cell *head = new Cell;//链表头用new建立
    head->next = NULL;
    head->value = vector[0];
    Cell *curr = head;//取头指针,之前的 head用于返回
    for(int i=0;i<vector.size(); i++){
        Cell *newCell = new Cell;
        newCell->next = NULL;
        newCell->value = vector[i];
        curr->next = newCell;
        newCell = curr;
    }
    return head;
}
Cell * ConvertToListRealRecur(Vector<int> &vector, int index)
{
    if(index >= vector.size())
    return NULL;
    Cell *curr = new Cell;
    curr->value = vector[index];
    curr->next = ConvertToListRealRecur(vector, index + 1);
    return curr;
}
Cell * ConvertToListRecur(Vector<int> vector)
{
return ConvertToRealRecur(vector, 0);
}

b)链表操作

int SumListIter(Cell *list){
    int sum = 0;
    Cell *curr = list;//curr指向头指针
    whlie(curr != NULl){
        sum += curr->value;
        curr = curr->next;
    }
    return sum;
}
int SumListRecur(Cell *list)
{
if(list == NULL)
return 0;
else
return list->value + SumListRecur(list->next);//链表递归经典操作
}

Problem 5: Linked List Trace

实现的功能就是把链表最后一个提到第一个,果然学指针最好的例子还是链表

//Link List Trave
void PopRocks(Cell * & mikey)//&传递,用于改变头指针
{
Cell *ptr;
  for (ptr = mikey; ptr->next != NULL; ptr = ptr->next)//将指针传递到结尾
  {
    /* Note: loop body intentionally left empty */  //想不到把,空循环
  }
  ptr->next = mikey;//将结尾连到开头
  ptr = ptr->next;//移到原来头指针
  mikey = mikey->next;//把原来的第二个数变成头指针
  ptr->next = NULL;//把原来的第一个指向空指针,即变成结尾
}

Problem 6: Append

记得以前数据结构老师讲过这个例子,怀念

void Append(Cell *& first,Cell * second){
    if(first == NULl)
    {
        first = second; //这就是为什么之前first要用&传递,因为当first为空时,first的头指针会改变
    }
    else{
        Append(first->next,second);//卧槽,亮瞎有木有
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值