Codeforces Round 36

Codeforces Round 36

蒟蒻的我并没有参加contest,比赛后打的,目前只写了4道题QWQ。

A.Garden

这这这真的就是一道水题

<题意概括>

给定n个水桶的数值,求在这n个水桶中能整除K的最大的数值。1<=n,k<=100.

直接枚举,因为只有一百,取最大的数。

Code

#include<cstdio>
#include<algorithm>
#define maxn 120
#include<cmath>
using namespace std;
int read(){
    int w=0;char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') w=w*10+c-48,c=getchar();
    return w;
}
int main(){
    int n,length,i,b,ans=2147483647;
    n=read();length=read();
    for(i=1;i<=n;i++){
        b=read();
        if(b==length){
            printf("1");return 0;
        }
        if(length%b==0) ans=min(ans,length/b);
    }
    printf("%d",ans);
}
Garden

B.Browser

<题意概括>

有一个1——n个窗口,有一个鼠标能在其中移动,每移动一个为一秒,在某个点时,

能关掉左边的窗口或右边的窗口(不包括它自己),时间均为一秒,求在这n个窗口中关掉除了[L,R[以外的窗口。

思路简单,but分的种类真的很恶心。一开始搞错了变量名WA了N次。。

分别对pos与l,r的关系进行分类。

#include<cstdio>
#include<algorithm>
#define maxn 120
#include<cmath>
using namespace std;
int read(){
    int w=0;char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') w=w*10+c-48,c=getchar();
    return w;
}
int main(){
    int t,n,pos,l,r;
    n=read();pos=read();l=read();r=read();
    if(l==r) {
        t=abs(pos-l);if(l!=1) t++;if(r!=n) t++;}
    else if(l==1&&r==n) t=0;
    else if(pos==l){
        if(l==1) t=r-l+1;
        else if(r==n) t=1;
        else t=2+r-l;
    }
    else if(pos==r){
        if(l==1) t=1;
        else if(r==n) t=r-l+1;
        else t=2+r-l;
    }
    else if(pos<l){
        if(r==n) t=1+l-pos;
        else t=2+r-pos;
    }
    else if(pos>r){
        if(l==1)  t=1+pos-r;
        else t=2+pos-l;
    }
    else {
        int mid=(l+r)/2;
        if(l==1){t=r-pos+1;}
        else if(r==n) t=pos-l+1;
        else if(pos<=mid){
            t=pos-l+1+r-l+1;
        }
        else{
            t=r-pos+1+r-l+1;
//            printf("mid:%d\n",mid);
        }
    }
    printf("%d",t);
    return 0;
}
Browser

D. Almost Acyclic Graph

<题意概括>

在一个有向图中,存不存在一条边,使删除它之后图中不再存在环。存在则输出YES,否则输出NO。

刚开始思路是在图中找出任意一个环,然后枚举环上的每一条边,如果找到符合条件的边之后,直接输出。

若找不到,则说明不存在,输出NO。But后来发现自己在判断有没有环时出了错,应该用拓扑排序的。。

所以经过大佬的启发换了另外一种,(不要问我为什么不用拓扑排序找环),分别对每个点进行DFS,找出这个

有向图中有几个不独立的环(就是若这个环与另外一个环有公共边,则不算这个环),若找出符合以上条件的

环大于1个,则说明不可能存在符合题意的这样一条边了。

NOTICE:要对搜索过的边标记一种状态,对环中的边标记为另外一种状态,对既不在环中也不在被搜索过的队列中标为另外一种状态,第一二种状态不能标成同个。

#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 600
using namespace std;
int vis[maxn],head[maxn],n,m,tot,cnt;
struct Edge{
    int to,next;
}e[250000];
int read(){
    int w=0;char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') w=w*10+c-48,c=getchar();
    return w;
}
void add(int x,int y){
    e[++tot]=(Edge){y,head[x]};
    head[x]=tot;
}
void dfs(int x){
    vis[x]=2;
    for(int i=head[x];i;i=e[i].next){
        if(vis[e[i].to]==2) cnt++;
        else if(!vis[e[i].to])dfs(e[i].to);
    }
    vis[x]=1;
}
int main(){
    int x,y,i,j;
    n=read();m=read();
    for(i=1;i<=m;i++){
        x=read();y=read();
        add(x,y);
    }
    for(i=1;i<=n;i++){
        cnt=0;
        memset(vis,0,sizeof(vis));
        dfs(i);
        for(j=1;j<=n&&cnt<=1;j++){
            if(!vis[j]) dfs(j);
        }
        if(cnt<=1) {printf("YES");return 0;}
    }
    printf("NO");
    return 0;
}
D. Almost Acyclic Graph

 

E. Physical Education Lessons

<题意概括>

给定N个工作日,初始状态为工作日,操作1区间全部变为非工作日,操作2区间全部变为工作日,输出每一次修改后工作日的数量。

由于这道题的数据范围太大了啊,不能用普通线段树实现,所以需要用离散化思想。

叶子节点维护的不再只是一个点,而是一个区间,原理与普通线段树一样。

#include<cstdio>
#include<set>
#include<algorithm>
#define maxn 1000050
using namespace std;
int a[maxn],l[maxn],r[maxn],k[maxn];
struct tree{
    int l,r,lazy,sum;
}t[maxn*4];
int read(){
    char c=getchar();int w=0;
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9'){
        w=w*10+c-48;c=getchar();
    }
    return w;
}
void pushdown(int rt){
    if(~t[rt].lazy){
        t[rt<<1].sum=(a[t[rt<<1].r]-a[t[rt<<1].l-1])*t[rt].lazy;
        t[rt<<1|1].sum=(a[t[rt<<1|1].r]-a[t[rt<<1|1].l-1])*t[rt].lazy;
        t[rt<<1].lazy=t[rt<<1|1].lazy=t[rt].lazy;t[rt].lazy=-1;
    }
}
void build(int rt,int l,int r){
    t[rt].l=l;t[rt].r=r;t[rt].lazy=-1;
    if(l==r){t[rt].sum=a[l]-a[l-1];return;}
    int mid=(l+r)>>1;
    build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
    t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
}
void change(int rt,int l,int r,int x){
    if(l<=t[rt].l&&t[rt].r<=r){
        t[rt].lazy=x;t[rt].sum=(a[t[rt].r]-a[t[rt].l-1])*x;return;
    }
    pushdown(rt);
    int mid=(t[rt].l+t[rt].r)>>1;
    if(l<=mid) change(rt<<1,l,r,x);
    if(r>mid) change(rt<<1|1,l,r,x);
    t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
}
set<int> balance;
int main(){
    int n,q,i,tot=0;
    n=read();q=read();
    for(i=1;i<=q;i++){
        l[i]=read();r[i]=read();k[i]=read();
        balance.insert(l[i]-1);balance.insert(r[i]);
    }
    if(*balance.begin()==0) balance.erase(balance.begin());
    balance.insert(n);
    for(set<int>::iterator i=balance.begin();i!=balance.end();i++){
        a[++tot]=*i;
    }
    for(i=1;i<=q;i++){
        l[i]=lower_bound(a+1,a+tot+1,l[i])-a;
        r[i]=lower_bound(a+1,a+tot+1,r[i])-a;
    }
    build(1,1,tot);
    for(i=1;i<=q;i++){
        change(1,l[i],r[i],k[i]-1);
        printf("%d\n",t[1].sum);
    }
    return 0;
}
Physical Education Lessons

 

 

posted @ 2018-01-18 20:30  Konnyaku  阅读(163)  评论(4编辑  收藏  举报