[大模擬]兩種方式解決Chat(UVALive-7047)大模擬

Part 1:題目地址

1.UVALive Chat UVALive - 7047
2.Virtual Judge Chat UVALive - 7047
3.HDU Chat UVALive - 7047

Part 2:解題思路和注意點

大模擬題的關鍵是使用的工具和編碼的嚴謹,由題意可以得到這個模擬題有很多插入,刪除,更換位置,訪問的操作,這些操作的總數不是很多,所以時間複雜度的問題可以放在後面,主要問題是實現這些功能。

我的做法是使用鏈表來完成這個模擬題,鏈表雖然寫起來比較麻煩,但是隻要注意指針的方向,及時控制好釋放空間,運用模塊化的思想,可以大大減少代碼量(當然相對於使用STL模板來說代碼量肯定還是多的)。

Chat這個題主要是九個操作:

1.Add u:

在隊列末尾增加一個priority爲u的人,如果這人已經在隊列裏面,就輸出same priority,否則輸出success.

2.Close u:

在隊列中刪除一個priority爲u的人,如果這個人不在隊列裏面,就輸出invalid priority,否則輸出success.

3.Chat w:

與隊列第一個人聊w句話,注意,如果存在有top標記的人,則要和這個人說w句,而不是隊列第一個人,如果隊列爲空就是empty,否則輸出success.

4.Rotate x:

將隊列中第x人移到隊列的第一個位置,如果x大於隊列人數,就輸出out of range,否則輸出success

5.Prior:

將隊列中priority最高的人移到隊列的第一個位置,如果隊列爲空就是empty,否則輸出success.

6.Choose x:

將隊列中priority爲x的人移到隊列的第一個位置,如果這個人不在隊列裏面,就輸出invalid priority,否則輸出success.

7.Top x:

將隊列中priority爲x的人設置爲Top,如果這個人不在隊列裏面,就輸出invalid priority,否則輸出success.

8.Untop:

取消當前的Top標記,如果當前沒有Top標記,就輸出no such person,否則輸出success.

9.bey(末尾處理):

在結尾,如果隊列中還有人,主人公要和所以說過話的人說bey,如果有Top標記的人,就要先和這個人說bey,然後再和其他人說bey。

這些操作主要是標記和更換隊列比較有難度,我選擇使用map來標記這個人是否在隊列中,然後使用鏈表來模擬隊列的情況,同時還有一個Top標記初始值設置爲0,如果有了Top操作則設置爲該人的priority值。

注意點:
1.Close操作的時候,如果刪除的人有top標記,一定要記得還原top標記。
2.可以利用Map的迭代器來找到隊列中priority最大的人。

Part 3:代碼部分

鏈表寫法

#include<bits/stdc++.h>
#define MAXN 100010
#define MAXE 100010
#define ll long long
#define eps 1e-6
#define PI acos(-1)
#define FILEIN freopen("in.txt","r",stdin)
#define FILEOUT freopen("out.txt","w",stdout)
#define CLR(x) memset(x,0,sizeof(x))
#define MEM(a,x) memset(a,x,sizeof(a))
#define PB(x) push_back(x)
#define PF(x) push_front(x)
#define rep(x,a,b) for(x=a;x<b;x++)
void sf(int &x){scanf("%d",&x);}
void sf(char &x){scanf("%c",&x);}
void sf(double &x){scanf("%lf",&x);}
void sf(char *x){scanf("%s",x);}
void sf(ll &x){scanf("%I64d",&x);}
void pf(int x){printf("%d",x);}
void pf(char x){printf("%c",x);}
void pf(double x){printf("%f",x);}
void pf(char *x){printf("%s",x);}
void pf(ll x){printf("%I64d",x);}
void pf(){printf("\n");}
const ll mod = 1e9+7;
const int maxn = 100010;
const int INF = 0x7ffffff;
const long long LINF = 0x7fffffffffffffff;
using namespace std;
ll q_pow(ll x,ll y){ll res=1;while(y){if(y&1) res=(res*x)%mod; y>>=1;x=(x*x)%mod;}return res;}
ll inv(ll x){return q_pow(x,mod-2);}
int Read(){int x=0,F=1;char C=getchar();while(C<'0'||C>'9'){if(C=='-')F=-F;C=getchar();}while(C>='0'&&C<='9'){x=x*10-'0'+C,C=getchar();}return x*F;}
int Trans(){char c;sf(c);int res;res=c-'0';return res;}

map<int,int>M;
map<int,int>::iterator it;
int TOPflag=0,LEN=0;
struct girls{
    int pri;int w;
    girls *next;
}*head;

girls*newnode(int x)
{
    girls*p;
    p=(girls*)malloc(sizeof(girls));
    p->pri = x;p->w = 0;p->next=NULL;
    return p;
}

void Add(int u){
    if(M[u]==1){printf("same priority.\n");return ;}
    else{
        if(head == NULL){
            girls *tem;
            tem = newnode(u);
            head = tem;
        }
        else{
            girls *tem,*p;
            tem = newnode(u);p=head;
            while(p->next!=NULL){p=p->next;}
            p->next = tem;
        }
        M[u]=1;LEN++;
        printf("success.\n");
    }
    return ;
}

void Close(int u){
    if(M[u] == 0){printf("invalid priority.\n");return ;}
    else
    {
        girls *pre,*tem;
        pre = tem = head;
        while(1){
            if(tem->pri == u){
                if(head==tem){head=head->next;}
                pre->next=tem->next;
                printf("close %d with %d.\n",tem->pri,tem->w);
                if(tem->pri == TOPflag){TOPflag = 0;}
                free(tem);
                break;
            }
            else{
                pre = tem;tem = tem->next;
            }
        }
        LEN--;M[u]=0;
    }
    return ;
}

void Chat(int w){
    if(LEN==0){printf("empty.\n");return ;}
    else{
        if(TOPflag != 0){
            girls *tem;tem = head;
            while(1){
                if(tem->pri == TOPflag){
                    tem->w+=w;
                    printf("success.\n");
                    break;
                }
                else {tem=tem->next;}
            }
        }
        else{head->w+=w;printf("success.\n");}
    }
    return ;
}

void Rotate(int num){
    if(num>LEN||num<1){printf("out of range.\n");return ;}
    else
    {
        int cnt=1;girls *tem,*pre;
        tem=pre=head;
        while(1){
            if(cnt == num){
                if(num == 1){printf("success.\n");break;}
                else{
                    pre->next=tem->next;
                    tem->next=head;
                    head=tem;
                    printf("success.\n");
                    break;
                }
            }
            else {cnt++;pre=tem;tem=tem->next;}
        }
    }
    return ;
}

void Prior(){
    if(LEN==0){printf("empty.\n");return;}
    else{
        it=--M.end();
        int MAX = (*it).first;
        girls *tem,*pre;
        tem=pre=head;
        while(1){
            if(tem->pri == MAX){
                if(tem == head){printf("success.\n");break;}
                pre->next = tem->next;
                tem->next = head;
                head = tem;
                printf("success.\n");
                break;
            }
            else{pre=tem;tem=tem->next;}
        }
        return ;
    }
}

void Choose(int u){
    if(M[u] == 0){printf("invalid priority.\n");return ;}
    else{
        girls *tem,*pre;tem=pre=head;
        while(1){
            if(tem->pri == u){
                if(tem == head){printf("success.\n");break;}
                pre->next = tem->next;
                tem->next = head;
                head = tem;
                printf("success.\n");
                break;
            }
            else{pre=tem;tem=tem->next;}
        }
        return ;
    }
}

void Top(int u){
    if(M[u] == 0){printf("invalid priority.\n");return ;}
    else{TOPflag = u;printf("success.\n");return ;}
}

void Untop(){
    if(TOPflag == 0){printf("no such person.\n");return ;}
    else{TOPflag = 0;printf("success.\n");return;}
}

void GOODBEY(){
    if(head == NULL){return ;}
    else{
        girls *tem,*pre;tem = pre = head;
        if(TOPflag !=0){
            while(tem->pri!=TOPflag){pre=tem;tem=tem->next;}
            if(tem==head){head=head->next;}
            else{
                pre->next=tem->next;
                if(tem->w!=0)
                    printf("Bye %d: %d\n",tem->pri,tem->w);
                free(tem);
            }
        }
        tem=head;
        while(tem != NULL){
            if(tem->w!=0)
                printf("Bye %d: %d\n",tem->pri,tem->w);
            girls *p;p=tem;
            tem=tem->next;
            free(p);
        }
    }
    return ;
}

/*void show()
{
    if(head == NULL) return ;
    girls *tem;
    tem = head;
    while(tem!=NULL){
        printf("%d-%d\n",tem->pri,tem->w);
        tem=tem->next;
    }
    printf("\n");
}*/

int main()
{
    int T;cin>>T;
    while(T--){
        head=NULL;TOPflag=0,LEN=0;
        int n,opid;cin>>n;
        M.clear();
        rep(opid,1,n+1){
            //show();
            string opname;int num;
            cin>>opname;
            cout<<"Operation #"<<opid<<": ";
            if(opname == "Add"){cin>>num;Add(num);}
            if(opname == "Close"){cin>>num;Close(num);}
            if(opname == "Chat"){cin>>num;Chat(num);}
            if(opname == "Rotate"){cin>>num;Rotate(num);}
            if(opname == "Prior"){Prior();}
            if(opname == "Choose"){cin>>num;Choose(num);}
            if(opname == "Top"){cin>>num;Top(num);}
            if(opname == "Untop"){Untop();}
        }
        GOODBEY();
    }
    return 0;
}

當然如果是使用列表則STL中的Vector也可以取代使用。
下面是STL版本:

#include<bits/stdc++.h>
#define MAXN 100010
#define MAXE 100010
#define ll long long
#define eps 1e-6
#define PI acos(-1)
#define FILEIN freopen("in.txt","r",stdin)
#define FILEOUT freopen("out.txt","w",stdout)
#define CLR(x) memset(x,0,sizeof(x))
#define MEM(a,x) memset(a,x,sizeof(a))
#define PB(x) push_back(x)
#define PF(x) push_front(x)
#define rep(x,a,b) for(x=a;x<b;x++)
void sf(int &x){scanf("%d",&x);}
void sf(char &x){scanf("%c",&x);}
void sf(double &x){scanf("%lf",&x);}
void sf(char *x){scanf("%s",x);}
void sf(ll &x){scanf("%I64d",&x);}
void pf(int x){printf("%d",x);}
void pf(char x){printf("%c",x);}
void pf(double x){printf("%f",x);}
void pf(char *x){printf("%s",x);}
void pf(ll x){printf("%I64d",x);}
void pf(){printf("\n");}
const ll mod = 1e9+7;
const int maxn = 100010;
const int INF = 0x7ffffff;
const long long LINF = 0x7fffffffffffffff;
using namespace std;
ll q_pow(ll x,ll y){ll res=1;while(y){if(y&1) res=(res*x)%mod; y>>=1;x=(x*x)%mod;}return res;}
ll inv(ll x){return q_pow(x,mod-2);}
int Read(){int x=0,F=1;char C=getchar();while(C<'0'||C>'9'){if(C=='-')F=-F;C=getchar();}while(C>='0'&&C<='9'){x=x*10-'0'+C,C=getchar();}return x*F;}
int Trans(){char c;sf(c);int res;res=c-'0';return res;}

map<int ,ll>M;
map<int ,ll>::iterator iter;
vector<int >V;
vector<int >::iterator it;
string opname;
int TOP =  0;

void init(){M.clear();V.clear();TOP=0;}

void Add(int t){
    if(M.find(t)!=M.end()){printf("same priority.\n");return;}
    V.push_back(t);M[t]=0;printf("success.\n");
}

void Close(int t){
    if(M.find(t)==M.end()){printf("invalid priority.\n");return;}
    printf("close %d with %lld.\n",t,M[t]);
    if(TOP==t){TOP=0;}
    it=find(V.begin(),V.end(),t);V.erase(it);M.erase(t);
}

void Chat(int t){
    if(V.empty()){printf("empty.\n");return ;}
    if(TOP) M[TOP]+=t;
    else{
        it=V.begin();
        M[(*it)]+=t;
    }
    printf("success.\n");
}

void Rotate(int t){
    if(t<1||t>V.size()){printf("out of range.\n");return ;}
    it=V.begin()+(t-1);
    int girl=(*it);V.erase(it);
    V.insert(V.begin(),girl);
    printf("success.\n");
}

void Prior(){
    if(M.empty()){printf("empty.\n");return;}
    iter=--M.end();
    int girl=(*iter).first;
    it=find(V.begin(),V.end(),girl);
    V.erase(it);V.insert(V.begin(),girl);
    printf("success.\n");
}

void Choose(int t){
    if(M.find(t) == M.end()){printf("invalid priority.\n");return ;}
    it=find(V.begin(),V.end(),t);
    V.erase(it);
    V.insert(V.begin(),t);
    printf("success.\n");
}

void Top(int t){
    if(M.find(t) == M.end()){printf("invalid priority.\n");return ;}
    TOP=t;printf("success.\n");return ;
}

void Untop(){
    if(TOP==0){printf("no such person.\n");return;}
    TOP=0;printf("success.\n");return;
}

int main()
{
    int cas,n,num;
    cin>>cas;
    while(cas--){
        init();
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>opname;
            printf("Operation #%d: ",i);
            if(opname == "Add"){cin>>num;Add(num);}
            if(opname == "Close"){cin>>num;Close(num);}
            if(opname == "Chat"){cin>>num;Chat(num);}
            if(opname == "Rotate"){cin>>num;Rotate(num);}
            if(opname == "Prior"){Prior();}
            if(opname == "Choose"){cin>>num;Choose(num);}
            if(opname == "Top"){cin>>num;Top(num);}
            if(opname == "Untop"){Untop();}
        }
        if(TOP!=0){
            it = find(V.begin(),V.end(),TOP);
            if(M[(*it)]>0) printf("Bye %d: %lld\n",(*it),M[(*it)]);
            V.erase(it);
        }
        for(it=V.begin();it!=V.end();it++){
            if(M[(*it)]>0) printf("Bye %d: %lld\n",(*it),M[(*it)]);
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章