Codeforces Round #499 (Div. 2) 题解

http://codeforces.com/contest/1011
(后附代码)


A

给一堆可用的字母,字母权值等于字母序号(a=1 b=2…),从小到大选一些字母出来排列,但是后一个和前一个至少要隔1个(a可以接c不能接a,b),一共选n个,问最小权值和。标记一下哪些字母出现了然后从小到大来一遍就好了。


B

有一些编了号的食物,有一些队伍要出征,每一只出征的队伍出征期间吃的食物的编号要一样,问最多可以出征几天。
二分天数,求食物最多可以供应多少支队伍。


C

有一艘飞船,在n个星球上遨游,路径1->2->3-> … ->n->1,离开每个星球和到达每个星球的时候都需要消耗一定的燃料(每个星球参数不同),问开始时至少要带多少燃料。

二分需要携带的燃料数,模拟一遍就完事儿。


D

交互题,1e9的数轴上有一个点,可以询问一个位置,对于大于小于等于的情况分别给出-1,0,1的答案。但是现在回答器坏了,有一个长度为n的01序列,并且序列无限循环,假设当前回答是第i个,如果序列上i是1.正确回答,否则给出正确答案的相反数,不超过60次问出这个点的位置。

注意到n<=30前n次询问1这个位置,答案肯定是1或者0,0好说,如果是-1,那肯定这个01序列这个位置是0,问n次问出来,后三十次直接二分询问就可以了。


E

给一个数组,任意选里面的数,求sum%k有多少种情况,n个数能组成的数一定是这n个数的gcd,由扩展欧几里得扩展得来,求gcd注意过滤0,求了n个数gcd还没完,因为可以%,所以还要跟k求gcd,就是这里忘了,挂的很惨。


F

给一棵树,叶子结点是布尔值,非叶子节点是逻辑运算符,问按序号从小到大依次对叶子结点值取反之后整棵树答案是多少(每次只更改一个) 1e6
大概是想了。。20min。先dfs一遍把每个节点初始值算出来,然后第二遍dfs三个东西,当前结点,当前结点为0/1时整棵树的答案,然后分情况往下传递,遇到叶子就可以直接知道答案了。

写的实在是简单粗暴 待会优化一下代码

这场没上紫是真的菜。


A


 //QWsin
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,x,y) for(int i=x;i<=y;++i)
using namespace std;

int vis[100];
char s[100];

int main()
{
    int n,k;cin>>n>>k;
    scanf("%s",s+1);
    for(int i=1;i<=n;++i) vis[s[i]-'a'+1]=1;

    int c=0,ans=0;
    for(int i=1;i<=26;++i) if(vis[i]) {
        ans+=i;
        if(++c>=k)break;++i;
    }

    if(c==k) cout<<ans<<endl;
    else cout<<-1<<endl;
    return 0;
}

B

//QWsin
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,x,y) for(int i=x;i<=y;++i)
using namespace std;

const int maxn=100+10;

int a[maxn],c[maxn];

int m,n;
inline int check(int mid)
{
    int cnt=0;
    for(int i=1;i<=100;++i)
    {
        cnt+=c[i]/mid;
    }
    return cnt>=m;
}

int main()
{
    cin>>m>>n;

    rep(i,1,n) {cin>>a[i];++c[a[i]];}

    if(m>n) {puts("0");return 0;}

    int l=1,r=n/m,mid,ans;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(check(mid))  l=mid+1,ans=mid;
        else r=mid-1;
    }

    cout<<ans<<endl;

    return 0;
}

C

//QWsin
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,x,y) for(int i=x;i<=y;++i)
using namespace std;

int n,m;

const int maxn=1000+10;

int a[maxn],b[maxn];

inline int check(double ans)
{
    double cur=m+ans;
    rep(i,1,n)
    {
        double t=cur/a[i];
        if((cur-=t) < m) return 0;
        if(i==n) t=cur/b[1];    
        else t=cur/b[i+1];
        if((cur-=t) < m) return 0;
    }
    return 1;
}

int main()
{
    cin>>n>>m;

    rep(i,1,n) cin>>a[i];
    rep(i,1,n) cin>>b[i];

    double l=0,r=1e9,mid;
    if(!check(1e9+1e8)) {puts("-1");return 0;}

    while(r-l > 1e-8)
    {
        mid=(l+r)/2;
        if(check(mid)) r=mid;
        else l=mid;
    }

    printf("%.8f",(l+r)/2);

    return 0;
}

D

//QWsin
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,x,y) for(int i=x;i<=y;++i)
using namespace std;

int n,m;

const int maxn=30+10;

int tr[maxn];

inline int query(int x){
    printf("%d\n",x);fflush(stdout);
    int t;cin>>t;return t;  
}

int OK=0;
inline int check(int x,int id)
{
    int k=query(x);
    if(tr[id]==-1) k=-k;
    if(k==-1) return 0;
    if(k==1) return 1;
    OK=1;return 0;
}

int main()
{
    cin>>m>>n;

    if(m==1) {query(1);return 0;}

    rep(i,1,n)
    {
        tr[i]=query(1);
        if(tr[i]==0) return 0;  
    }

    int l=1,r=m,mid,c=0;
    while(l<=r)
    {
        mid=(l+r)>>1;if(++c == n+1) c=1;
        if(check(mid,c)) l=mid+1;
        else r=mid-1;

        if(OK) {return 0;}
    }

    return 0;
}

E

//QWsin
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,x,y) for(int i=x;i<=y;++i)
using namespace std;

const int maxn=100000+10;

int a[maxn];

int gcd(int a,int b){return b?gcd(b,a%b):a;}

int main()
{
    int n,k;cin>>n>>k;
    rep(i,1,n) {scanf("%d",a+i);a[i]%=k;}

    int g=0;
    rep(i,1,n){
        if(g==0) g=a[i];
        else if(a[i]) g=gcd(g,a[i]);
    }

    if(g==0) {printf("1\n0");return 0;}
    g=gcd(g,k); 

    int sz=(k-1)/g;
    cout<<sz+1<<endl;
    rep(i,0,sz) printf("%d ",i*g);
    return 0;
}


F

//QWsin
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,x,y) for(int i=x;i<=y;++i)
using namespace std;

const int maxn=1000000+10;

char s[maxn][5];
int val[maxn],ch[maxn][2];


int vv[maxn],ans[maxn];

int DFS(int cur)
{
    int ret;
    if(s[cur][0]=='I') ret= val[cur];
    if(s[cur][0]=='A'){
        ret= DFS(ch[cur][0]) & DFS(ch[cur][1]);
    }
    if(s[cur][0]=='O')
    {
        ret= DFS(ch[cur][0]) | DFS(ch[cur][1]);
    }
    if(s[cur][0]=='X')
    {
        ret= DFS(ch[cur][0]) ^ DFS(ch[cur][1]);
    }
    if(s[cur][0]=='N') ret= !DFS(ch[cur][0]);
    vv[cur]=ret;return ret;
}

void dfs(int cur,int ans1,int ans0)
{
    int l=ch[cur][0],r=ch[cur][1];
    if(s[cur][0]=='I')
    {
        int t;
        if(val[cur]==0) t=ans1;
        else t=ans0;
        ans[cur]=t;
//      printf("%d %d\n",cur,t);
        return ;    
    }
    if(s[cur][0]=='A')
    {
        if(vv[l]==0 && vv[r]==1) {dfs(l,ans1,ans0);dfs(r,ans0,ans0);}
        if(vv[l]==1 && vv[r]==0) {dfs(l,ans0,ans0);dfs(r,ans1,ans0);}
        if(vv[l]==0 && vv[r]==0) {dfs(l,ans0,ans0);dfs(r,ans0,ans0);}
        if(vv[l]==1 && vv[r]==1) {dfs(l,ans1,ans0);dfs(r,ans1,ans0);}
    }
    if(s[cur][0]=='O')
    {
        if(vv[l]==0 && vv[r]==1) {dfs(l,ans1,ans1);dfs(r,ans1,ans0);}
        if(vv[l]==1 && vv[r]==0) {dfs(l,ans1,ans0);dfs(r,ans1,ans1);}
        if(vv[l]==0 && vv[r]==0) {dfs(l,ans1,ans0);dfs(r,ans1,ans0);}
        if(vv[l]==1 && vv[r]==1) {dfs(l,ans1,ans1);dfs(r,ans1,ans1);}
    }
    if(s[cur][0]=='X')
    {
        if(vv[l]==0 && vv[r]==1) {dfs(l,ans0,ans1);dfs(r,ans1,ans0);}
        if(vv[l]==1 && vv[r]==0) {dfs(l,ans1,ans0);dfs(r,ans0,ans1);}
        if(vv[l]==0 && vv[r]==0) {dfs(l,ans1,ans0);dfs(r,ans1,ans0);}
        if(vv[l]==1 && vv[r]==1) {dfs(l,ans0,ans1);dfs(r,ans0,ans1);}
    }
    if(s[cur][0]=='N') dfs(ch[cur][0],ans0,ans1);
}

int main()
{
    int n;cin>>n;

    rep(i,1,n)
    {
        scanf("%s",s[i]);
        if(s[i][0]=='I')  scanf("%d",val+i);
        else if(s[i][0]!='N'){
            int a,b;
            scanf("%d%d",&a,&b);if(a>b) swap(a,b);
            ch[i][0]=a;
            ch[i][1]=b;
        }
        else{
            int a;
            scanf("%d",&a);
            ch[i][0]=a;
        }
    }

    memset(ans,-1,sizeof ans);
    vv[1]=DFS(1);
    dfs(1,1,0);

    for(int i=1;i<=n;++i) if(ans[i]!=-1)printf("%d",ans[i]);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值