Codeforces Round #532 (Div. 2)

Posted mountaink

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #532 (Div. 2)相关的知识,希望对你有一定的参考价值。

A. Roman and Browser

题意:给出k,让你求b,使所有位置c(c满足$ c = b + i * k$) 的标签全部消失,使1和-1的数量相差最大,求b。

枚举。

技术分享图片
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100010;
int n,k;
int aa,bb;
int p;
int v[110];
int main(){
    while(cin>>n>>k)
    {
        p=1000*k;
        for(int i=1;i<=n;i++)
        {
            int u;
            cin>>v[i];
            if(v[i]>0)aa++;
            else bb++;
        }
        int ans=0;
        for(int b=1;b<=n;b++)
        {
            int xx=aa,yy=bb;
            for(int j=b-1;j>0;j--)
            {
                if((b-j)%k==0)
                {
                    if(v[j]>0)xx--;
                    else yy--;
                }
            } 
            for(int j=b;j<=n;j++)
            {
                if((j-b)%k==0)
                {
                    if(v[j]>0)xx--;
                    else yy--;
                }
            }
            ans=max(ans,abs(xx-yy));
        }
        cout<<ans<<endl;
    }
}
View Code

 

B. Build a Contest

题意:依次给出数字,当凑足了1-n时输出1,否则输出0。

记录当前位置有几个数字了,凑满数字就所有vis(次数数组减一),一开始居然想到用线段树维护维护这个减一操作和查询次数,因为觉得n太大了每次都扫一遍会超时。后来发现,由于m时固定的,所以扫描n的次数最多是m/n次,每次要n的时间,所以就是o(m)的时间。所以暴力不会出事。

技术分享图片
#include<bits/stdc++.h>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=100010;
int n,m;
int a[maxn];
int vis[maxn];
string ans;
int main(){
    while(cin>>n>>m)
    {
        CLR(vis,0);
        ans="";
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&a[i]);
        }
        int tot=0;
        for(int i=1;i<=m;i++)
        {
            if(vis[a[i]]==0){
                tot++;
                vis[a[i]]=1;
            }else{
                vis[a[i]]++;
            }
            if(tot<n)ans+="0";
            else{
                ans+="1";
                tot=0;
                for(int j=1;j<=n;j++)
                {
                    vis[j]--;
                    if(vis[j]>0)tot++;
                }
            }
        }
        cout<<ans<<endl;
    }
}
View Code

 

C. NN and the Optical Illusion

初中计算几何题,设外半径为R,半径为r,可以列方程,会解二元一次方程就可以,直接套求根公式。

技术分享图片
#include<bits/stdc++.h>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=100010;
const double pai=acos(-1.0);
double n,r,R,p,die;
int main(){
    while(cin>>n>>r)
    {
        p=cos(2*pai/n);
    //    cout<<p<<endl;
        die=(4*r*p-4*r)*(4*r*p-4*r)-4*(2+2*p)*(2*r*r*p-2*r*r);
        double ans=((4*r-4*r*p)+sqrt(die))/(4+4*p);
        printf("%.8f
",ans);
    }
}
View Code

 

D. Dasha and Chess

待补

 

E. Andrew and Taxi

题意:给出衣服有向图,每条边的权值是代表使这条边反向所需要的能力,现在希望使整幅图无环,并且只要使一条边反向了,其他所有权值小于等于这条边的边都可以免费反向。

题解:显然是一个可以二分的题目,因为对所有边进行合法操作必然能得到一个合法的图,这个limit越小则限制越严格。

对于一个二分出来的权值k,我们可以先把所有权值小于等于k的边全部取消,而其他边全部变成拓扑偏序关系,由于取消掉了这些边,所以这些边的影响相当于是最后由我决定的,只要我能写出合法的拓扑序列,那我按照这个拓扑序列来决定边的方向即可。合法的拓扑序列即拓扑完成后元素个数等于n(否则说明有环,元素还在队列里)。

不断二分k,那怎么根据拓扑序列来决定边的方向呢?其实就是看每个元素的拓扑序号是多少,比如u和v,如果u有一条连向v的有向边,但u的拓扑序号却比v的拓扑序号大,说明在拓扑序列中,u在v的后面,所以这条边要被反向,即输出。

技术分享图片
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int n,m;
struct node{
    int u,v;
    ll w;
};
struct edge{
    int to,Next;
}e[maxn];
vector<node >a;
int u,v,tot,head[maxn],d[maxn],top[maxn];
ll w,l,r,mid; 
void addv(int u,int v){
    e[++tot].to=v;
    e[tot].Next=head[u];
    head[u]=tot;
}
bool toposort(){
    queue<int >q;
    int cnt=0; 
    for(int i=1;i<=n;i++)
    {
        if(d[i]==0){
            q.push(i);
        }
    }
    while(!q.empty())
    {
        int u=q.front();
        top[u]=++cnt;
        q.pop();
        for(int i=head[u];i!=-1;i=e[i].Next)
        {
            int v=e[i].to;
            d[v]--;
            if(d[v]==0)
            {
                q.push(v);
            }
        }
    }
    if(cnt==n)return true;
    return false;
}
void buildGraph(ll mid){
    clr(head,-1),tot=0;
    clr(d,0);
    for(int i=0;i<m;i++)
    {
        int st=a[i].u,ed=a[i].v;
        ll val=a[i].w;
        if(val>mid){
            addv(st,ed);
            d[ed]++;
        }
    }
}
vector<int >ans;
int main(){
    while(cin>>n>>m)
    {
        a.clear();
        ans.clear();
        l=0,r=0;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%lld",&u,&v,&w);
            a.push_back({u,v,w});
            r=max(r,w);
        }
        while(l<r)
        {
            mid=(l+r)>>1;
            buildGraph(mid);
            if(toposort()){
                r=mid;
            }else {
                l=mid+1;
            }
        }
        buildGraph(r);
        toposort();
        for(int i=0;i<m;i++)
        {
            if(a[i].w<=r && top[a[i].u]>top[a[i].v])ans.push_back(i+1);
        }
        int si=ans.size();
        printf("%lld %d
",r,si);
        for(int i=0;i<si;i++)
        {
            printf("%d%c",ans[i]," 
"[i==si-1]);
        }
        
    }
}
View Code

 

F. Ivan and Burgers

待补。

以上是关于Codeforces Round #532 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Codeforces Round #726 (Div. 2) B. Bad Boy(贪心)

Codeforces Global Round 19

Codeforces Educational Codeforces Round 67

Codeforces Round 1132Educational Round 61