The Blocks Problem

The Blocks Problem

题目链接:The Blocks Problem

题目概述:给你n个方块,有四种操作:

  1. move a onto b,把a和b上面的方块都放回原来位置,然后把a放到b上面;
  2. move a over b,把a上面的放回原处,然后把a放在b所在的方块堆的上面;
  3. pile a onto b,把b上面的放回原来位置,然后把a和a上面的方块整体放到b上面;
  4. pile a over b,把a和a上面的方块整体放到b所在堆的上面。

Input:

10
move 9 onto 1
move 8 over 1
move 7 over 1
move 6 over 1
pile 8 over 6
pile 8 over 5
move 2 over 1
move 4 over 9
quit

Output:

0: 0
1: 1 9 2 4
2:
3: 3
4:
5: 5 8 7 6
6:
7:
8:
9:

解题思路:这里我用了类的方式,过于麻烦。可不必采用这种方式。接下来说下代码思路:
主要数据结构是short place[25]list<short> n_list[25] place用来记录当前木块在那一列上,值为最底部木块的值。n_list 记录没一列上放置的木块。move 两个操作比较简单,pile两个操作需要考虑 a 在一列的中间的情况。详细情况看代码。


最终代码:

#include <iostream>
#include <list>
#include <string>
#include <algorithm>
using namespace std;

class Block{
    public:
        Block(int n):length(n){
            for(int i=0;i < n ;i++){
                    place[i]=i;
                    n_list[i].push_back(i);
            }
        }
        void moveOnto(int a,int b){
            if(this->isCounfict(a,b)){
                this->reSet(a);
                this->reSet(b);
                n_list[place[b]].push_back(a);
                n_list[place[a]].pop_back();
                place[a]=place[b];
            }

        }
        void moveOver(int a,int b){
            if(this->isCounfict(a,b)){
                this->reSet(a);
                n_list[place[b]].push_back(a);
                n_list[place[a]].pop_back();
                place[a]=place[b];
            }
        }
        void pileOnto(int a,int b){
            if(this->isCounfict(a,b)){
                this->reSet(b);
                int flag = false;
                int couser= place[a];
                for (list<short>::iterator i = n_list[couser].begin(); i != n_list[couser].end(); ++i){
                    if(*i==a){
                        flag = true;
                    }
                    if(flag){
                        n_list[place[b]].push_back(*i);
                        place[*i]=place[b];
                    }

                }
                while(n_list[couser].back()!=a){
                    n_list[couser].pop_back();
                }
                n_list[couser].pop_back();
            }
        }
        void pileOver(int a,int b){

            if(this->isCounfict(a,b)){
                int flag = false;
                int couser= place[a];
                for (list<short>::iterator i= n_list[couser].begin(); i != n_list[couser].end(); ++i){
                    if(*i==a){
                        flag = true;
                    }
                    if(flag){
                        n_list[place[b]].push_back(*i);
                        place[*i]=place[b];
                    }
                }


                while(n_list[couser].back()!=a){
                    n_list[couser].pop_back();
                }
                n_list[couser].pop_back();
            }
        }
        void printArr(){

            for(int j = 0; j < length; j++)
            {
                cout <<j<<":";
                for (list<short>::iterator i = n_list[j].begin(); i != n_list[j].end(); ++i){
                    cout<<" "<<*i;
                }
                cout<<endl;
            }
        }

    private:
        int length;
        short place[25];
        list<short> n_list[25];
        bool isCounfict(int a,int b){
            if(a==b || place[a]==place[b])
                return false;
            return true;
        }
        void reSet(int n){
            int couser= place[n];
            int current=n_list[couser].back();
            while(current!=n){
                place[current] = current;
                n_list[current].push_back(current);
                n_list[couser].pop_back();
                current=n_list[couser].back();
            }
        }
};

int main()
{
   int n=0;
   int a=0,b=0;
   string commands;
   cin>>n;
   Block *block= new Block(n);
   while(true){
        cin >> commands;
        if(commands=="move"){
            cin >> a;
            cin >> commands;
            if(commands =="onto"){
                cin>>b;
                block->moveOnto(a,b);
            }
            if(commands == "over"){
                cin>>b;
                block->moveOver(a,b);
            }
        }
        if(commands== "pile"){
            cin >> a;
            cin >> commands;
            if(commands =="onto"){
                cin>>b;
                block->pileOnto(a,b);
            }
            if(commands == "over"){
                cin>>b;
                block->pileOver(a,b);
            }
        }
        if(commands== "quit"){
            block->printArr();
            break;
        }
   }
    delete block;

   return 0;

}
The Readers-Writer problem is a classic synchronization problem in computer science. In this problem, multiple threads need access to a shared resource. However, some of these threads only need to read from the resource, while others need to write to it. To ensure correctness and avoid data corruption, we need to implement a solution that allows concurrent reading but exclusive writing. One common solution to this problem is to use a semaphore or a lock to coordinate access to the shared resource between readers and writers. Here's an implementation of the Readers-Writer problem using a mutex and a condition variable in C++: ```c++ #include <mutex> #include <condition_variable> class ReadersWriter { public: ReadersWriter() : readers_count(0), writer_active(false) {} void start_read() { std::unique_lock<std::mutex> lock(m); while (writer_active) { // wait until no writer is active cv_read.wait(lock); } ++readers_count; } void end_read() { std::unique_lock<std::mutex> lock(m); --readers_count; if (readers_count == 0) { cv_write.notify_one(); // notify waiting writers } } void start_write() { std::unique_lock<std::mutex> lock(m); while (writer_active || readers_count > 0) { // wait until no readers or writers are active cv_write.wait(lock); } writer_active = true; } void end_write() { std::unique_lock<std::mutex> lock(m); writer_active = false; cv_write.notify_one(); // notify waiting writers cv_read.notify_all(); // notify waiting readers } private: std::mutex m; std::condition_variable cv_read; std::condition_variable cv_write; int readers_count; bool writer_active; }; ``` In this implementation, we use a mutex `m` to ensure exclusive access to the shared variables `readers_count` and `writer_active`. We also use two condition variables `cv_read` and `cv_write` to coordinate access between readers and writers. When a thread wants to start reading, it first acquires the lock `m` and then waits on the condition variable `cv_read` until there are no active writers. If there are active writers, the thread blocks until it's notified by a writer that it has finished writing. Once it's safe to read, the thread increases the `readers_count` and releases the lock `m`. When a thread wants to end reading, it first acquires the lock `m` and then decreases the `readers_count`. If there are no more readers, the thread notifies waiting writers using the condition variable `cv_write` and releases the lock `m`. When a thread wants to start writing, it first acquires the lock `m` and then waits on the condition variable `cv_write` until there are no active readers or writers. If there are active readers or writers, the thread blocks until it's notified by a reader or writer that it has finished accessing the shared resource. Once it's safe to write, the thread sets the `writer_active` flag to true and releases the lock `m`. When a thread wants to end writing, it first acquires the lock `m` and then sets the `writer_active` flag to false. The thread then notifies waiting writers using the condition variable `cv_write` and waiting readers using the condition variable `cv_read`, and releases the lock `m`.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只放纵的死魂灵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值