奇怪的练习(1)

这是第一次,我打算一直每次选3个题(提高+/省选-),看最后多少分(第一次交),今天算是10+70+30=110,真的好低。。
T1
这题其实挺简单,树状数组&&二分,然后我就写炸了,10分,唉,真无语,然后看了题解,发现这题还可以set来做,不过是逆向思维。
代码1:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#define ll long long
using namespace std;
inline int lowbit(int x){
    return x&-x;
}
int n,m;
int t[50001];
inline int query(int x){
    int sum=0;
    while(x){
        sum+=t[x];
        x-=lowbit(x);
    }
    return sum;
}
inline void update(int x,int v){
    while(x<=n){
        t[x]+=v;
        x+=lowbit(x);
    }
}
int solve(int x){
    if(query(x)-query(x-1)==0){
        return 0;
    }
    int l=1,r=x;
    int mid;
    while(l<r){
        mid=(l+r)>>1;
        if(query(mid)-query(l-1)==mid-l+1){
            l=mid+1;
        }
        else{
            r=mid;
        }
    }
    int sum=0;
    if(query(x)==x){
        sum+=x;
    }
    else{
        sum+=x-l;
    }
    l=x,r=n;
    while(l<r){
        mid=(l+r)>>1;
        if(query(mid)-query(l-1)==mid-l+1){
            l=mid+1;
        }
        else{
            r=mid;
        }
    }
    if(query(n)-query(x-1)==n-x+1){
        sum+=n-x;
    }
    else{
        sum+=l-x-1;
    }
    return sum;
}
stack<int> s;
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        update(i,1);
    }
    for(int i=1;i<=m;i++){
        char ch;
        cin>>ch;
        if(ch=='D'){
            int x;
            scanf("%d",&x);
            update(x,-1);
            s.push(x);
        }
        else if(ch=='R'){
            int x=s.top();
            s.pop();
            update(x,1);
        }
        else{
            int x;
            scanf("%d",&x);
            printf("%d\n",solve(x));
        }
    }
    return 0;
}

代码2:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#define ll long long
using namespace std;
set<int> s;
int n,m;
stack<int> q;
int main(){
    scanf("%d %d",&n,&m);
    s.insert(0);
    s.insert(n+1);
    for(int i=1;i<=m;i++){
        char ch;
        cin>>ch;
        if(ch=='D'){
            int x;
            scanf("%d",&x);
            s.insert(x);
            q.push(x);
        }
        else if(ch=='R'){
            int x;
            x=q.top();
            q.pop();
            s.erase(s.find(x));
        }
        else{
            int x;
            scanf("%d",&x);
            set<int>::iterator it=s.lower_bound(x);
            if(*it==x){
                printf("0\n");
                continue;
            }
            int num=*it-*(--it)-1;
            printf("%d\n",num);
        }
    }
    return 0;
}

T2
这题首先想搜索,然后就看见你n<=16,果断状压dp,然后就又写挂了,70分,看了题解之后,发现少了一维状态,加上就A了,才感觉自己智障了。。
代码1:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
int n;
char a[20][101];
int len[20];
int g[20][20];
int f[1000001];
int main(){
    scanf("%d",&n);
    int all=1<<n;
    int ans=0;
    for(int i=1;i<=n;i++){
        scanf("%s",a[i]);
        len[i]=strlen(a[i]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(a[i][len[i]-1]==a[j][0]){
                g[i][j]=1;
            }
        }
    }
    for(int i=1;i<=n;i++){
        f[1<<(i-1)]=len[i];
    }
    for(int s=0;s<all;s++){
        for(int i=1;i<=n;i++){
            if((s>>(i-1))&1){
                for(int j=1;j<=n;j++){
                    if(!((s>>(j-1))&1)){
                        if(g[i][j]){
                            f[s+(1<<(j-1))]=max(f[s+(1<<(j-1))],f[s]+len[j]);
                        }
                    }
                }
            }
        }
        ans=max(ans,f[s]);
    }
    printf("%d",ans);
    return 0;
}

代码2:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
int n;
char a[20][101];
int len[20];
int g[20][20];
int f[20][500001];
int main(){
    scanf("%d",&n);
    int all=1<<n;
    int ans=0;
    for(int i=1;i<=n;i++){
        scanf("%s",a[i]);
        len[i]=strlen(a[i]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(a[i][len[i]-1]==a[j][0]){
                g[i][j]=1;
            }
        }
    }
    for(int i=1;i<=n;i++){
        f[i][1<<(i-1)]=len[i];
    }
    for(int s=0;s<all;s++){
        for(int i=1;i<=n;i++){
            if((s>>(i-1))&1){
                for(int j=1;j<=n;j++){
                    if(!((s>>(j-1))&1)){
                        if(g[i][j]){
                            f[j][s+(1<<(j-1))]=max(f[j][s+(1<<(j-1))],f[i][s]+len[j]);
                        }
                    }
                }
                ans=max(ans,f[i][s]);
            }
        }
    }
    printf("%d",ans);
    return 0;
}

T3
这题是我选的最后一题,一看题,多重背包呀,裸题,然后准备写。我就想,先看看数据范围吧,好开数组,就看见数据范围大得要命,这题算部分30分吧,虽然没写(滑稽),一会儿写了这个题再来补上吧。。

posted @ 2017-09-11 13:47  玫葵之蝶  阅读(125)  评论(0编辑  收藏  举报