码迷,mamicode.com
首页 > 其他好文 > 详细

UVA1607 Gates 与非门电路 (二分)

时间:2015-08-01 18:42:51      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:

题意:给你一个按发生时间的序列,表示与非门电路的输入,一开始全部输入是x,现在要改成尽量少的x,实现相同的功能。

题解:电路功能只有4中0,1,x,非x。那么如果一开始x改变了,输出结果不变,那么说明是常量电路。否则一定可以只用一个x来实现相同的功能,因为从全为0到全为1的过程中一定会有某个时刻,改变了一个位置上的值结果也随之改变。

由于m很大,不能一个一个地试,二分来找。判断的时候,如果输入端编号小于等于输入参数k,那么就为1,否则为0。如果mid跑出来的结果和全为1的一致,那么,mid+1以后的位置一定都不是了,区间变成[L,mid],否则mid以及之前的一定都不是,区间变成[mid+1,R]。

#include<bits/stdc++.h>
using namespace std;

const int maxm = 200005;
int n,m;
int o[maxm],s1[maxm],s2[maxm];


inline int Run(int k)
{
    //cout<<"fuck\n";
    for(int i = 1; i <= m ;i++){
        int x = s1[i];
        int y = s2[i];
        int a = x<0?-x<=k:o[x];
        int b = y<0?-y<=k:o[y];
        o[i] = !(a&b);
    }
    return o[m];
}

int main()
{
    //freopen("in.txt","r",stdin);
    int T; scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= m; i++){
           scanf("%d%d",s1+i,s2+i);
        }
        int v0 = Run(0), vn = Run(n);

        if(v0 == vn) {
            for(int i = 0; i < n; i++) putchar(0);
            putchar(\n); continue;
        }

        int L = 0, R = n;
        int mid;
        while(L<R) {
            mid = (L + R)>>1;
            if(Run(mid) == vn) R = mid;
            else L = mid+1;
        }
        for(int i = 1; i < L; i++) putchar(1);
        putchar(x);
        for(int i = L+1; i <= n; i++) putchar(0);
        if(T) putchar(\n);
    }
    return 0;
}

 

UVA1607 Gates 与非门电路 (二分)

标签:

原文地址:http://www.cnblogs.com/jerryRey/p/4694370.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!