程序设计思维与实践 Week9 作业

A-咕咕东的目录管理器

题目描述

咕咕东的雪梨电脑的操作系统在上个月受到宇宙射线的影响,时不时发生故障,他受不了了,想要写一个高效易用零bug的操作系统 —— 这工程量太大了,所以他定了一个小目标,从实现一个目录管理器开始。前些日子,东东的电脑终于因为过度收到宇宙射线的影响而宕机,无法写代码。他的好友TT正忙着在B站看猫片,另一位好友瑞神正忙着打守望先锋。现在只有你能帮助东东!

初始时,咕咕东的硬盘是空的,命令行的当前目录为根目录 root。

目录管理器可以理解为要维护一棵有根树结构,每个目录的儿子必须保持字典序。
https://vjudge.net/contest/368394#problem/A

题意分析

按照题目要求将每个功能逐个写成函数实现或整体封装成一个类即可,注意要在整体上把握好每个功能的复杂度,否则很容易tle
下面是主要的方法实现思路:
MKDIR:关键是每次插入新目录的时候要不断向上更改目录的大小,复杂度为log(树高),目的是使SZ功能的复杂度为O(1)
RM:同上,向上维护目录大小即可,复杂度为log(树高)
UNDO:使用结构体存储操作名称,当前节点和目的节点
TREE:采用懒更新的思想,可以通过一个bool类型的变量来标记文件目录在一次tree操作后是否更改过。如果没有更改过,则直接输出已经保存好的结果。

代码

#include
#include
#include
#include
#include
#include
int t,q;
int cn=0;
using namespace std;
pair lc;
struct ml{
    string name;
    map content;
    ml* mom;
    int size; 
    bool tag;
    vector pre;
    vector bac;
};
void update(ml* t, int delta){
    if(t==NULL)return;
    t->size+=delta;
    update(t->mom,delta);
}
vector record;
bool if_changed;
struct command{
    string op,tn;
    ml* current;
    ml* tp;
    command(string op, string tn, ml* current, ml* tp):op(op),tn(tn),current(current),tp(tp){
        
    }
};
command com("","",NULL,NULL);
vector c;
ml* cu=NULL; 
ml* dlptr = NULL;
ml* lml;
vector ans;
void mkdir(ml* current,string s){
    if(current->content.find(s)==current->content.end()){
        ml* nm = new ml;
        nm->name=s;
        nm->mom = current;
        nm->size=1;
        update(cu,1);
        //pre.push_back(s);
        current->content[s] = nm;
        //lc.first = "MKDIR";
        //lc.second = s;
        //ml* node=current;
        //while(node){
        //  node->size++;
        //  node->tag=false;
        //  node=node->mom;
        //}
        printf("OK\n");
        com.op = "MKDIR";
        com.tn = s;
        com.current = current;
        com.tp = nm;
        c.push_back(com);
        if_changed = true;
    }
    else{
        printf("ERR\n");
    }
}
void rm(ml* current, string s){
    auto it = current->content.find(s);
    if(it==current->content.end()){
        printf("ERR\n");
    }
    else{
        command tempc("RM",s,current,it->second);
        c.push_back(tempc);
        if_changed = true;
        /*dlptr = current->content[s];
        current->content.erase(s);
        ml* node=current;
        while(node){
            node->size--;
            node->tag=false;
            node=node->mom;
        }
        lc.first="RM";
        lc.second=s;*/
        update(current,-1*(it->second->size));
        current->content.erase(s);
        printf("OK\n");
    }
}
void cd(string s){
    if(s==".."){
        if(cu->mom!=NULL){
            //lc.first="CD";
            //lml = cu;
            command tempc("CD",s,cu,cu->mom);
            c.push_back(tempc);
            if_changed=true;
            cu=(cu->mom);
            printf("OK\n");
        }
        else{
            printf("ERR\n");
        }
        return;
    }
    auto it = cu->content.find(s);
    if(it==cu->content.end()){
        printf("ERR\n");
        return;
    }
    command tempc("CD",s,cu,it->second);
    c.push_back(tempc);
    if_changed = true;
    cu=it->second;
    //lc.first="CD";
    //lml = cu;
    //cu=current->content[s];
    
    printf("OK\n");
}
int sz(ml* current){
    /*if(!current->content.size()){
        return 1;
    }
    int num=0;
    for(auto ziml : current->content){
        num+=sz(ziml.second);
    }
    return 1+num;*/
    return current->size;
}
void ls(ml* current){
    if(!current->content.size()){
        printf("EMPTY\n");
    }
    else if(current->content.size()<=10){
        for(auto x:current->content){
            //cout<content.begin();
        while(cnt--){
            //cout<first<first.c_str());
            x++;
        }
        printf("...\n");
        cnt=5;
        x = current->content.end();
        while(cnt--){
            x--;
        }
        for(auto it=x;it!=current->content.end();it++){
            //cout<first<first.c_str());
        }
    }
}
void pre(int n,ml* i){
    record.push_back(i->name);
    n--;
    if(n==0)return;
    for(auto it=i->content.begin();it!=i->content.end();it++){
        int csize=it->second->size;
        if(csize>=n){
            pre(n,it->second);
            return;
        }
        else{
            pre(csize,it->second);
            n-=csize;
        }
    }
}
void bac(int n,ml* i){
    for(auto it=i->content.rbegin();it!=i->content.rend();it++){
        int csize=it->second->size;
        if(csize>=n){
            bac(n,it->second);
            return;
        }
        else{
            bac(csize,it->second);
            n-=csize;
        }
    }
    record.push_back(i->name);
}
void dfs(ml* i){
    record.push_back(i->name);
    for(auto it=i->content.begin();it!=i->content.end();it++){
        dfs(it->second);
    }
}
void tree(ml* current){
    if(current->size==1){
        printf("EMPTY\n");
    }
    else if(current->size<=10){
        if(if_changed==true){
            record.clear();
            dfs(current);
            if_changed = false; 
        }
        for(string i:record) printf("%s\n",i.c_str());
    }
    else{
        if(if_changed==true){
            record.clear();
            pre(5,current);
            bac(5,current);
            if_changed = false;
        }
        for(int i=0;i<5;i++)printf("%s\n",record[i].c_str());
        printf("...\n");
        for(int i=9;i>=5;i--)printf("%s\n",record[i].c_str());
    }
}
/*void dfstree(ml* current){
    if(ans.size()>=5 && cn-current->size>5){
        cn-=current->size;
        return;
    }
    ans.push_back(current->name);
    cn--;
    if(!current->content.size()) return;
    for(auto x:current->content){
        dfstree(x.second);
    }
}
void tree(ml* current){
    if(!current->content.size()){
        printf("EMPTY\n");
    }
    else {
        cn=current->size;
        ans.clear();
        dfstree(current);
        if(ans.size()<=10){
            for(auto x:ans){
                //cout<content.erase(lc.second);
        ml* node=cu;
        while(node){
            node->size--;
            node=node->mom;
        }
        printf("OK\n");
    }
    else if(lc.first=="RM"){
        ml* nm = dlptr;
        nm->name=lc.second;
        nm->mom = cu;
        nm->size=1;
        cu->content[lc.second] = nm;
        ml* node=cu;
        while(node){
            node->size++;
            node=node->mom;
        }
        printf("OK\n");
    }
    else if(lc.first=="CD"){
        cu=lml;
        printf("OK\n");
    }
    else{
        printf("ERR\n");
    }
}
*/
void undo(){
    if(!c.size()) printf("ERR\n");
    else{
        auto comm=c[c.size()-1];
        c.pop_back();
        if(comm.op=="RM"){
            cu->content[comm.tn] = comm.tp;
            update(cu,comm.tp->size);
        }
        else if(comm.op=="MKDIR"){
            update(cu,-1);
            cu->content.erase(comm.tn);
        }
        else {
            cu=comm.current;
        }
        if_changed=true;
        printf("OK\n");
    }
}
int main(){
    
    /*lc = make_pair("NULL","NULL");
    cu = new ml;
    cu->name = "root";
    cu->mom = NULL;
    cu->size=1;
    lml = cu;*/
    cin>>t;
    while(t--){
    cu = new ml;
    cu->name = "root";
    cu->mom = NULL;
    cu->size = 1;
    cu->content.clear();
    c.clear();
    record.clear();
    if_changed = true;
        cin>>q;
        while(q--){
            cin>>op;
            if(op=="MKDIR"){
                cin>>ss;
                mkdir(cu,ss);
            }
            else if(op=="RM"){
                cin>>ss;
                rm(cu,ss);
            }
            else if(op=="CD"){
                cin>>ss;
                cd(ss);
            }
            else if(op=="SZ"){
                cout<

B-

题目描述

最近,东东沉迷于打牌。所以他找到 HRZ、ZJM 等人和他一起打牌。由于人数众多,东东稍微修改了亿下游戏规则:

所有扑克牌只按数字来算大小,忽略花色。
每张扑克牌的大小由一个值表示。A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K 分别指代 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13。
每个玩家抽得 5 张扑克牌,组成一手牌!(每种扑克牌的张数是无限的,你不用担心,东东家里有无数副扑克牌)
理所当然地,一手牌是有不同类型,并且有大小之分的。

举个栗子,现在东东的 "一手牌"(记为 α),瑞神的 "一手牌"(记为 β),要么 α > β,要么 α < β,要么 α = β。

那么这两个 "一手牌",如何进行比较大小呢?首先对于不同类型的一手牌,其值的大小即下面的标号;对于同类型的一手牌,根据组成这手牌的 5 张牌不同,其值不同。下面依次列举了这手牌的形成规则:

大牌:这手牌不符合下面任一个形成规则。如果 α 和 β 都是大牌,那么定义它们的大小为组成这手牌的 5 张牌的大小总和。

对子:5 张牌中有 2 张牌的值相等。如果 α 和 β 都是对子,比较这个 "对子" 的大小,如果 α 和 β 的 "对子" 大小相等,那么比较剩下 3 张牌的总和。

两对:5 张牌中有两个不同的对子。如果 α 和 β 都是两对,先比较双方较大的那个对子,如果相等,再比较双方较小的那个对子,如果还相等,只能比较 5 张牌中的最后那张牌组不成对子的牌。

三个:5 张牌中有 3 张牌的值相等。如果 α 和 β 都是 "三个",比较这个 "三个" 的大小,如果 α 和 β 的 "三个" 大小相等,那么比较剩下 2 张牌的总和。

三带二:5 张牌中有 3 张牌的值相等,另外 2 张牌值也相等。如果 α 和 β 都是 "三带二",先比较它们的 "三个" 的大小,如果相等,再比较 "对子" 的大小。

炸弹:5 张牌中有 4 张牌的值相等。如果 α 和 β 都是 "炸弹",比较 "炸弹" 的大小,如果相等,比较剩下那张牌的大小。

顺子:5 张牌中形成 x, x+1, x+2, x+3, x+4。如果 α 和 β 都是 "顺子",直接比较两个顺子的最大值。

龙顺:5 张牌分别为 10、J、Q、K、A。

作为一个称职的魔法师,东东得知了全场人手里 5 张牌的情况。他现在要输出一个排行榜。排行榜按照选手们的 "一手牌" 大小进行排序,如果两个选手的牌相等,那么人名字典序小的排在前面。

不料,此时一束宇宙射线扫过,为了躲避宇宙射线,东东慌乱中清空了他脑中的 Cache。请你告诉东东,全场人的排名。
https://vjudge.net/contest/368394#problem/B

题意分析

根据不同的情况分类判断即可。

代码

#include
#include
#include
#include
#include
#include
#include
using namespace std;
int re[3];
int rf[3];
int ja,jb;
int judge(int o1,int o2, int o3,int o4,int o5,int* cao){
    int arr[] = {o1,o2,o3,o4,o5};
    sort(arr,arr+5);
    if(arr[0]==1 && arr[1]==10 && arr[2]==11 && arr[3]==12 && arr[4]==13){
        return 8;
    }
    bool flag=true;
    for(int i=0;i<4;i++){
        if(arr[i]!=(arr[i+1]-1)){
            flag = false;
            break;
        }
    }
    if(flag){
        cao[0]=arr[0];
        return 7;
    }
    if(arr[0]==arr[1]&&arr[1]==arr[2]&&arr[2]==arr[3]&&arr[3]==arr[4]){
        cao[0]=arr[0];
        cao[1]=arr[0];
        return 6;
    }
    if((arr[0]==arr[1] && arr[1]==arr[2] && arr[2]==arr[3] && arr[0]!=arr[4])){
        cao[0]=arr[0];
        cao[1]=arr[4];
        return 6;
    }
    if((arr[1]==arr[2] && arr[2]==arr[3] && arr[3]==arr[4] && arr[0]!=arr[4])){
        cao[0]=arr[4];
        cao[1]=arr[0];
        return 6;
    }
    if(arr[0]==arr[1] && arr[2]==arr[3] && arr[3]==arr[4]){
        cao[0]=arr[2];
        cao[1]=arr[0];
        return 5;
    }
    if(arr[0]==arr[1] && arr[1]==arr[2] && arr[3]==arr[4]){
        cao[0]=arr[2];
        cao[1]=arr[3];
        return 5;
    }
    if(arr[0]==arr[1]&&arr[1]==arr[2]){
        cao[0]=arr[0];
        cao[1]=arr[3]+arr[4];
        return 4;
    }
    if(arr[1]==arr[2]&&arr[2]==arr[3]){
        cao[0]=arr[1];
        cao[1]=arr[0]+arr[4];
        return 4;
    }
    if(arr[2]==arr[3]&&arr[3]==arr[4]){
        cao[0]=arr[2];
        cao[1]=arr[0]+arr[1];
        return 4;
    }
    if(arr[0]==arr[1] && arr[3]==arr[4]){
        if(arr[0]>arr[3]){
            cao[0]=arr[0];
            cao[1]=arr[3];
            cao[2]=arr[2];
        }
        else{
            cao[0]=arr[3];
            cao[1]=arr[0];
            cao[2]=arr[2];
        }
        return 3;
    }
    if(arr[1]==arr[2]&&arr[3]==arr[4]){
        if(arr[1]>arr[3]){
            cao[0]=arr[1];
            cao[1]=arr[3];
            cao[2]=arr[0];
        }
        else{
            cao[0]=arr[3];
            cao[1]=arr[1];
            cao[2]=arr[0];
        }
        return 3;
    }
    if (arr[0]==arr[1] && arr[2]==arr[3]){
        if(arr[1]>arr[3]){
            cao[0]=arr[1];
            cao[1]=arr[3];
            cao[2]=arr[4];
        }
        else{
            cao[0]=arr[3];
            cao[1]=arr[1];
            cao[2]=arr[4];
        }
        return 3;
    }
    flag=true;
    int cn;
    for(int i=0;i<4;i++){
        if(arr[i]==(arr[i+1])){
            flag = false;
            cn=i;
            break;
        }
    }
    if(!flag){
        int sum=0;
        for(int i=0;i<5;i++){
            if(arr[i]!=arr[cn]) sum+=arr[i];
        }
        cao[0]=arr[cn];
        cao[1]=sum;
        return 2;
    }
    else{
        int sum=0;
        for(int i=0;i<5;i++){
            sum+=arr[i];
        }
        cao[0]=sum;
        return 1;
    }
}
struct par{
    string name;
    int a[5];
}p[100010];
bool cmp(par& a,par& b){
    ja=judge(a.a[0],a.a[1],a.a[2],a.a[3],a.a[4],re);
    jb=judge(b.a[0],b.a[1],b.a[2],b.a[3],b.a[4],rf);
    if(ja==jb){
        if(ja==8){
            return a.name>b.name;
        }
        if(ja==7){
            if(re[0]==rf[0]){
                return a.name>b.name;
            }
            else return re[0]b.name;
                }
                else return re[1]b.name;
                }
                else return re[1]b.name;
                }
                else return re[1]b.name;
                    }
                    else return re[2]b.name;
                }
                else return re[1]b.name;
            }
            else return re[0]>n;
    for(int j=0;j>na>>pai;
        for(int i=0;i=pai[i]){
                temp[cnt++]=pai[i]-'0';
            }
            else if(pai[i]=='1'){
                temp[cnt++]=10;
                i++;
            }
            else if(pai[i]=='A') temp[cnt++]=1;
            else if(pai[i]=='J') temp[cnt++]=11;
            else if(pai[i]=='Q') temp[cnt++]=12;
            else temp[cnt++]=13;
        }
        for(int i=0;i<5;i++){
            p[j].a[i]=temp[i];
        }
        p[j].name = na;
    }
    sort(p,p+n,cmp);
    for(int i=n-1;i>=0;i--){
        printf("%s\n",p[i].name.c_str());
    }
    return 0;
}

你可能感兴趣的:(程序设计思维与实践 Week9 作业)