10.13考试爆炸记

嗯没错我就是又炸了
水一波题解
(1)split
给定 n,k ;
如果 n 能被分成相差为k的两块
则分
对两块进行相同的处理
求能分成多少块
n109

啊对啊其实题面就是题解

然而我傻逼地写了一个计算对应大小的块的贡献
还搭配着奇数特判才勉强A掉…

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline int read(){
    int i=0,f=1;
    char ch;
    for(ch=getchar();!isdigit(ch);ch=getchar())
        if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar())
        i=(i<<3)+(i<<1)+(ch^48);
    return i*f;
}
int buf[1024];
inline void write(int x){
    if(!x){putchar('0');return ;}
    if(x<0){putchar('-');x=-x;}
    while(x){buf[++buf[0]]=x%10,x/=10;}
    while(buf[0]) putchar(buf[buf[0]--]+48);
    return ;
}
int n,k,ans,tmp;
int ksm(int a,int b){
    int ret=1;
    while(b){
        if(b&1) ret*=a;
        b>>=1;
        a*=a;
    }
    return ret;
}
int check(int a,int b){
    while(a<b) a*=2;
    return a;
}
signed main(){
    n=read();k=read();
    ans=1;
    if(k%2){
        tmp=n;
        while(tmp>k){
            if(!((tmp-k)%2)) ++ans;
            else break;
            tmp=(((tmp+k)/2)%2)?(tmp+k)/2:(tmp-k)/2;
        }
        write(ans);
        return 0;
    }else{
        for(int i=0;(n-k*(2*i+1))>=check(2,2*i+1);++i){
            if(!((n-k*(2*i+1))%check(2,2*i+1))) ++ans;
            int d=check(2,2*i+1)<<1;
            for(int j=1;(n-k*(2*i+1))>=d;++j){
                if(!(((n-k*(2*i+1)))%d)) ++ans;
                d<<=1;
            }
        }   
        write(ans);
        return 0;
    }
}

(2)run
n 人于长为l的环形跑道上,以不同起点不同速度不同方向奔跑
编号大的碰到编号小的便淘汰编号小的
求比赛进行时间,用分数表示
n105

很显然有一种 n2 暴力
我们可以用链表和堆优化

wuvin的所谓 O(n) 做法貌似有锅啊

%%%ksda47832338

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#include<bitset>
#include<queue>
using namespace std;
inline int read(){
    int i=0,f=1;
    char ch;
    for(ch=getchar();!isdigit(ch);ch=getchar())
        if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar())
        i=(i<<3)+(i<<1)+(ch^48);
    return i*f;
}
int buf[1024];
inline void write(int x){
    if(!x){putchar('0');return ;}
    if(x<0){putchar('-');x=-x;}
    while(x){buf[++buf[0]]=x%10,x/=10;}
    while(buf[0]) putchar(buf[buf[0]--]+48);
    return ;
}
#define stan 111111
int l,T;
const double inf=1e30;
int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
struct data{
    int u, d;
    void standard(){
        int x;
        if(d<0) u=-u,d=-d;
        x=gcd(u,d);
        u/=x,d/=x;
    }
    operator double()const{ return d?(double)u/d:inf;}
    data(){}
    data(int x, int y) {
        int a;
        if(y<0) x=-x,y=-y;
        a=gcd(x,y);
        u=x/a;
        d=y/a;
    }
};
struct penguin{
    int id;
    int d, v, last, next;
    bool operator <(const penguin &a) const{ return d<a.d; }
    inline void cut();
}pen[stan];
void penguin::cut() {
    pen[last].next = next;
    pen[next].last = last;
}
inline data getIntersect(int i, int j){
    int v1=pen[i].v,s1=pen[i].d;
    int v2=pen[j].v,s2=pen[j].d;
    if(v1>v2&&s1>s2) s1-=l;
    else if(v2>v1&&s2>s1) s2-=l;
    return data(s1-s2,v2-v1);
}
struct Pair{
    int a,b;
    data t;
    Pair(){}
    Pair(int _a, int _b):a(_a),b(_b),t(getIntersect(_a,_b)){}
    bool operator < (const Pair &p)const{ return t > p.t; }
};
bitset<stan>bits;
priority_queue<Pair>que;
int main(){
    T=read();
    while(T--){
        Pair t;
        int n=read();
        l=read();
        for(int i=1;i<=n;++i) 
            pen[i].d=read(),pen[i].id=i;
        for(int i=1;i<=n;++i)
            pen[i].v=read();
        sort(pen+1,pen+n+1);
        bits.reset();
        while(!que.empty()) que.pop();
        que.push(Pair(1,2)); 
        pen[1].last=n,pen[1].next=2;
        que.push(Pair(n,1));
        pen[n].last=n-1,pen[n].next=1;
        for(int i=2;i<n;++i){
            que.push(Pair(i,i+1));
            pen[i].last=i-1;
            pen[i].next=i+1;
        }
        while(!que.empty()) {
            t = que.top();
            que.pop();
            if(bits.test(t.a) || bits.test(t.b)) continue;
            if(pen[t.a].id < pen[t.b].id) {
                if(pen[t.a].last==t.b) break;
                que.push(Pair(pen[t.a].last, t.b));
                pen[t.a].cut();
                bits.set(t.a);
            }else {
                if(t.a==pen[t.b].next) break;
                que.push(Pair(t.a, pen[t.b].next));
                pen[t.b].cut();
                bits.set(t.b);
            };
        }
        write(t.t.u);putchar('/');write(t.t.d);
        puts("");
    }
    return 0;
}

(3)wall
给一个图,有 n 个端点与m条边
每条边有两个对应端点与权值
其中某些边在平面上围成了一个封闭的区块
求拆除最少的边破除所有封闭的区块
如果有多种方案,求权值最小的一种

考场上光顾着调第二题去了

裸的最大生成树

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline int read(){
    int i=0,f=1;
    char ch;
    for(ch=getchar();!isdigit(ch);ch=getchar())
        if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar())
        i=(i<<3)+(i<<1)+(ch^48);
    return i*f;
}
int buf[1024];
inline void write(int x){
    if(!x){putchar('0');return ;}
    if(x<0){putchar('-');x=-x;}
    while(x){buf[++buf[0]]=x%10,x/=10;}
    while(buf[0]) putchar(buf[buf[0]--]+48);
    return ;
}
#define stan 111111
#define sten 333333
int T,n,m,cnt,a,ans,fa[stan];
struct e{
    int a,b,c;
}edge[sten];
bool cmp(e a,e b){
    return a.c>b.c;
}
int getfa(int x){
    if(fa[x]==x) return x;
    else return fa[x]=getfa(fa[x]);
}
signed main(){
    T=read();
    while(T--){
        cnt=0;ans=0;
        n=read();m=read();
        for(int i=1;i<=n;++i)
            fa[i]=i;
        for(int i=1;i<=n;++i){
            a=read();
            a=read();
        }
        for(int i=1;i<=m;++i){
            edge[i].a=read();
            edge[i].b=read();
            edge[i].c=read();
            ans+=edge[i].c;
        }
        sort(edge+1,edge+m+1,cmp);
        for(int i=1;i<=m;++i){
            int x=getfa(edge[i].a);
            int y=getfa(edge[i].b);
            if(x!=y){
                fa[x]=y;
                ++cnt;
                ans-=edge[i].c;
            }
        }
        write(m-cnt);putchar(' ');write(ans);
        puts("");
    }
    return 0;
}

return 0;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值