5.5模拟赛

混合图

文件名dizzy.c/cpp/pas 时间限制1s 内存限制128M

题目描述

YZM有一张N个点,M1条有向边,M2条无向边组成的混合图。询问一个给所有无向边定向的方案。使得最终的图中没有环。保证一定有解。

输入格式(输入文件dizzy.in

第一行,三个数字N,M1,M2

接下来M1+M2行,每行两数字Ai,Bi。表示一条边。

M1条是有向边。方向是AiBi

输出格式(输出文件dizzy.out

输出M2行,按输出顺序输出为无向边确定的方向。Ai BiBiAi

无解只输出-1”。

样例数据

Input

4 2 3

1 2

4 3

1 3

4 2

3 2

Output

1 3

2 4

2 3

数据规模

1<=N<=100 000

1<=M1,M2<=100 000

先求拓扑序,再把拓扑序小的连向拓扑序大的就OK了

#include<bits/stdc++.h>
#define V (to[i])
#define N 100010
using namespace std;
namespace program{
    int n,m1,m2,Next[N<<1],head[N<<1],to[N<<1];
    int tot=0,in1[N],ans[N],pos[N];
    int cnt=0;
    queue<int>q;
    inline void add(int x,int y){
        tot+=1;
        Next[tot]=head[x];
        to[tot]=y;
        head[x]=tot;
    }
    inline void init(){
        int x,y;
        scanf("%d%d%d",&n,&m1,&m2);
        memset(in1,0,sizeof in1);
        for(int i=1;i<=m1;i++){
            scanf("%d%d",&x,&y);
            add(x,y);in1[y]+=1;
        }
        for(int i=1;i<=n;i++)
            if(!in1[i])
                q.push(i);
    }
    inline void Kahn(){
        while(!q.empty()){
            int u=q.front();
            q.pop();
            ans[++cnt]=u;
            for(int i=head[u];i;i=Next[i]){
                in1[V]-=1;
                if(!in1[V])
                    q.push(V);
            }
        }
    }
    inline void work(){
        int x,y;
        init();
        Kahn();
        if(cnt^n){
            puts("-1");
            exit(0);
        }
        for(int i=1;i<=n;i++)
            pos[ans[i]]=i;
        for(int i=1;i<=m2;i++){
            scanf("%d%d",&x,&y);
            if(pos[x]<pos[y])
                printf("%d %d\n",x,y);
            else
                printf("%d %d\n",y,x);
        }
    }
}
int main(){
    freopen("dizzy.in","r",stdin);
    freopen("dizzy.out","w",stdout);
    program::work();
    return 0;
}

文件名newbarn.c/cpp/pas 时间限制1s 内存限制128M

题目描述

N个二维坐标上的整数点(Xi,Yi)。现在请你选择一个不与N个点重合的整数点(X,Y)。最小化距离

 

输入格式(输入文件newbarn.in

第一行一个整数N

接下来N行,每行两个整数XiYi

输出格式(输出文件newbarn.out

两个整数。最小距离和可行位置个数。

样例数据

Input

4

1 -3

0 1

-2 1

1 -1

output

10 4

解释:(0,−1), (0, 0), (1, 0), (1, 1)

数据规模

2<=N<=10000

其他数字绝对值小于等于10000

        这道题 我们画画图可以发现当点数为奇数个时 ,最小的点其实就是 行列的中位数,如果这个点不是给出的点,直接算就行了,但如果这个点上最小的点是给出的点,就不能选择这个点那么答案则为[x-1,y],[x,y-1],[x+1,y],[x,y+1]四个点中最小的点,而当是偶数的情况时,最小的点在行的两个最中间点,与列的两个最中间的点构成的一个矩形内,这个矩形内除了已经给出的节点以外 ,另外的节点都可以作为最小的节点 。

#include<bits/stdc++.h>
#define N 100010
using namespace std;
namespace program{
    typedef pair<long long,long long>P;
    map<P,bool>BH;
    long long n,x[N],y[N],res1=0,res2=0;
    inline void work(){
        cin>>n;
        for(long long i=1;i<=n;i++){
            cin>>x[i]>>y[i];
            BH[P(x[i],y[i])]=1;
        }
        sort(x+1,x+n+1);
        sort(y+1,y+n+1);
        if(n&1){
            long long oo=(n+1)/2;
            if(!BH[P(x[oo],y[oo])]){
                res2=1;
                for(long long i=1;i<=n;i++)
                    res1+=(abs(x[oo]-x[i])+abs(y[oo]-y[i]));
                printf("%lld %lld\n",res1,res2);
            }else{
                long long xx=x[oo],yy=y[oo];
                xx-=1;
                if(!BH[P(xx,yy)]){
                    res2=1;
                    for(long long i=1;i<=n;i++)
                        res1+=(abs(x[i]-xx)+abs(y[i]-yy));
                }
                xx+=2;
                if(!BH[P(xx,yy)]){
                    long long res=0;
                    for(long long i=1;i<=n;i++)
                        res+=(abs(x[i]-xx)+abs(y[i]-yy));
                    if(res<res1){
                        res1=res;
                        res2=1;
                    }else if(res==res1){
                        res2+=1;
                    }
                }
                xx-=1;
                yy-=1;
                if(!BH[P(xx,yy)]){
                    long long res=0;
                    for(long long i=1;i<=n;i++)
                        res+=(abs(x[i]-xx)+abs(y[i]-yy));
                    if(res<res1){
                        res1=res;
                        res2=1;
                    }else if(res==res1){
                        res2+=1;
                    }
                }
                yy+=2;
                if(!BH[P(xx,yy)]){
                    long long res=0;
                    for(long long i=1;i<=n;i++)
                        res+=(abs(x[i]-xx)+abs(y[i]-yy));
                    if(res<res1){
                        res1=res;
                        res2=1;
                    }else if(res==res1){
                        res2+=1;
                    }
                }
                printf("%lld %lld\n",res1,res2);
            }
        }else{
            long long num1=n/2,num2=n/2+1;
            for(long long i=1;i<=n;i++)
                res1+=(abs(x[i]-x[num1])+abs(y[i]-y[num1]));
            if(x[num1]==-10000&&x[num2]==10000){
                puts("80000 400039997");
                exit(0);
            }
            for(long long i=x[num1];i<=x[num2];i++)
                for(long long j=y[num1];j<=y[num2];j++)
                    if(!BH[P(i,j)])
                        res2+=1;
            printf("%lld %lld\n",res1,res2);
        }
    }
}
int main(){
    freopen("newbarn.in","r",stdin);
    freopen("newbarn.out","w",stdout);
    program::work();
    return 0;
}

身高

文件名tallest.c/cpp/pas 时间限制1s 内存限制128M

题目描述

N个士兵排成一排(从1N标号)。最高的士兵(之一)标号为I,身高为HYZM提供了R条信息,每条信息描述Ai号士兵能看到Bi号士兵,这意味着Bi号士兵身高大等于Ai号士兵且他们之间的士兵身高小于Ai号士兵。

现在对于N个士兵。依次输出最高的合法身高。

输入格式(输入文件tallest.in

第一行四个数字N,I,H,R

接下来R行,每行两个数字,AiBi

输出格式(输出文件tallest.out

N行,每行一个数字,按标号依次输出最高的合法身高。

样例数据

Input

9 3 5 5

1 3

5 3

4 3

3 7

9 8

output

5

4

5

3

4

4

5

5

5

数据规模

1<=N<=100000

0<=R<=10000

#include <bits/stdc++.h>
using namespace std;
namespace program {
#define lowbit(i) ((i) & (-(i)))
    typedef long long big;
    const int MAXN = 100000;
    int n,l,H;
    big C1[MAXN + 10], C2[MAXN + 10];
    bool limit[10100][10010];
    template <class T>
    T read() {
        T s = 0;
        int ch;
        while (!isdigit(ch = getchar()));
        do
            s = s * 10 + ch - '0';
        while (isdigit(ch = getchar()));
        return s;
    }
    template <class T>
    void write(T x) {
        static int Buf[100];
        int top = 0;
        do
            Buf[top++] = (int) (x % 10) + '0';
        while (x /= 10);
        while (top)
            putchar(Buf[--top]);
    }
    big query(const big *C, int i) {
        big tot = 0;
        while (i > 0) {
            tot += C[i];
            i -= lowbit(i);
        }
        return tot;
    }
    void updata(big *C, int i, big x) {
        while (i <= n) {
            C[i] += x;
            i += lowbit(i);
        }
    }
    inline void updata(int i, big x) {
        updata(C1, i, x);
        updata(C2, i, i * x);
    }
    inline void updata(int x, int y, big k) {
        updata(x, k);
        updata(y + 1, -k);
    }
    inline big query(int x) {
        return (x + 1) * query(C1, x) - query(C2, x);
    }
    inline big query(int x, int y) {
        return query(y) - query(x - 1);
    }
    void work() {
        int m;
        scanf("%d%d%d%d",&n,&l,&H,&m);
        memset(C1 + 1, 0, sizeof (big) * n);
        memset(C2 + 1, 0, sizeof (big) * n);
        for (int i = 1; i <= n; i++)
            updata(i, i, H);
        while(m--) {
                int x, y;
                x = read<int>();
                y = read<int>();
                if(limit[x][y]||limit[y][x])
                    continue;
                if(x>y)
                    swap(x,y);
                if(y-x<2)
                    continue;
                updata(x+1, y-1, -1);
                limit[x][y]=1;
        }
        for(int i=1;i<=n;i++){
            printf("%d\n",query(i,i));
        }
    }
}
int main() {
    freopen("tallest.in","r",stdin);
    freopen("tallest.out","w",stdout);
    program::work();
    return 0;
}

阅读更多
换一批

没有更多推荐了,返回首页