Codeforces Round #442 (Div. 2)

第一次打cf,感觉很有意思。

llj大佬A了三题的时候还没有看到a题在讲什么,谷歌翻译把 a 翻译成了1,愉快被坑。

写了的都是些简单的签到题,写得太慢还掉了rating,,,,,

 

a.模拟

站一个点往两边小的那个跑。

//Twenty
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
using namespace std;
typedef long long LL;
int n,a,b,c,now,ans,l[10],r[10],ll[10],rr[10];
int main()
{
    cin>>n>>a>>b>>c;
    l[1]=2; r[1]=3; ll[1]=a; rr[1]=b;
    l[2]=3; r[2]=1; ll[2]=c; rr[2]=a;
    l[3]=1; r[3]=2; ll[3]=b; rr[3]=c;
    int now=1,cnt=0;
    while(cnt<=n) {
        cnt++;
        if(cnt>=n) break;
        if(ll[now]<=rr[now]) {ans+=ll[now]; now=l[now]; }
        else {ans+=rr[now]; now=r[now]; }
    }
    cout<<ans<<endl;
    return 0;
}
View Code

 

b.发现mod b答案相同的点是一起的。当一坨长度够了就break。

//Twenty
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
using namespace std;
typedef long long LL;
const int maxn=1e5+5;

inline int read() {
    int ret=0,f=1; char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';
    return ret*f;
}

int n,k,m,a[maxn],pos[maxn],cnt[maxn],pr[maxn],fl,now;

int main()
{
    n=read(); k=read(); m=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=n;i++) {
        now=a[i]%m;
        if(pos[now]) pr[i]=pos[now];
        cnt[now]++;
        pos[now]=i;
        if(cnt[now]==k) {now=i; fl=1; break;}
    }
    if(!fl) printf("No\n");
    else {
        printf("Yes\n");
        printf("%d ",a[now]);
        while(pr[now]) {
            printf("%d ",a[pr[now]]);
            now=pr[now];
        }
        printf("\n");
    }
    return 0;
}
View Code

 

c.发现最大不过能加9*9=81,枚举从max(0,n-81) ~n,判断可行即可。

注意要升序输出,WA了两发。。。。

//Twenty
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
using namespace std;
typedef long long LL;
int n,ans[100];
int main()
{
    scanf("%d",&n);
    for(int i=max(1,n-81);i<=n;i++) {
        int tp=i,tpp=i;
        while(tp) {
            tpp+=tp%10;
            tp/=10;
        }
        if(tpp==n) ans[++ans[0]]=i;
    }
    printf("%d\n",ans[0]);
    for(int i=1;i<=ans[0];i++) 
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}
View Code

 

d.转换模型成求逆序对最多的人的逆序对的个数。

一定是最后面一个人。随便怎么模拟乱搞一下就可以了。

//Twenty
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
using namespace std;
typedef long long LL;
const int maxn=300005;
int n,a[maxn],x,ans,now,as[maxn];
int main()
{
    scanf("%d",&n);
    as[0]=1;
    for(int i=1;i<=n;i++) {
        scanf("%d",&x);
        a[x]=1;
        if(x!=n&&a[x+1]!=1) ans++;
        else {
            if(x==n) {
                now=n; a[now]=1;
                while(a[now-1]==1) {now--; ans--; }
            }
            else {
                a[x]=1;
                if(now!=x+1) ans++;
                else {
                    now=x;
                    while(now>=2&&a[now-1]==1) {
                        now--;
                        ans--;
                    }
                } 
            }
        }
        as[i]=ans+1;
    }
    for(int i=0;i<=n;i++) printf("%d ",as[i]);
    printf("\n");
    return 0;
}
View Code

 

e.听说是2_sat;

不会。

 

f.

llj大佬给我讲得好像很有道理的样子,结果WA了。

//Twenty
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
const int maxn=200005;
using namespace std;
typedef long long LL;
LL ans;
int n,a[maxn],l[maxn],r[maxn],q[maxn],h[maxn],ll[50],rr[50],que[maxn],ql=1,qr;

void read(int &x) {
    int ret=0,f=1; char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';
    x=ret*f;
}

int main()
{
    read(n);
    for(int i=1;i<=n;i++) read(a[i]);
    for(int i=1;i<=n;i++) {
        while(ql<=qr&&a[i]>=a[que[qr]]) {qr--;}
        if(ql<=qr) l[i]=que[qr]+1;
        else l[i]=1;
        que[++qr]=i;
        for(int j=1;j<=30;j++) {
            if(a[i]&(1<<j-1)) ll[j]=i;
            else if(ll[j]&&(!q[i]||q[i]<ll[j])) q[i]=ll[j];
        } 
    }
    ql=1; qr=0;
    for(int i=n;i>=1;i--) {
        while(ql<=qr&&a[i]>=a[que[qr]]) {qr--;}
        if(ql<=qr) r[i]=que[qr]-1;
        else r[i]=n;
        que[++qr]=i;
        for(int j=1;j<=30;j++) {
            if(a[i]&(1<<j-1)) rr[j]=i;
            else if(rr[j]&&(!h[i]||h[i]>rr[j])) h[i]=rr[j];
        } 
    }
    for(int i=1;i<=n;i++) {
        if(q[i]&&h[i])
            ans+=((LL)(i-l[i]+1)*(r[i]-i+1)-(LL)(i-q[i])*(h[i]-i));
    }
    printf("%I64d\n",ans);
    return 0;
}
    
View Code

 

posted @ 2017-10-17 17:24  啊宸  阅读(340)  评论(0编辑  收藏  举报