UVa 1607 (二分) Gates

这道题真的有点“神”啊。= ̄ω ̄=

因为输入都是x,所以整个电路的功能一共就四种:0, 1, x,!x

所以就确定了这样一个事实:如果电路的输出是常数,那么所有的输入都可以优化成常数。

否则,只需要将一个输入变为变量即可,其他的全部为常数。

从00...0到11...1,在1的数量增多的过程中一定有一个位置,使得output(k) = output(n), output(k-1) = output(0)。output(k)表示前面有k个1,有n-k个0.

那么将第k为设为变量即可,k前面输出0,k后面输出1即可。

k的位置可以用二分来确定。

 1 #include <cstdio>
 2
 3 const int maxn = 200000 + 10;
 4 int a[maxn], b[maxn], o[maxn];
 5 int n, m;
 6
 7 int output(int k)
 8 {
 9     for(int i = 1; i <= m; i++)
10     {
11         int va = a[i] < 0 ? -a[i] > k : o[a[i]];
12         int vb = b[i] < 0 ? -b[i] > k : o[b[i]];
13         o[i] = !(va && vb);
14     }
15     return o[m];
16 }
17
18 int main()
19 {
20     //freopen("in.txt", "r", stdin);
21
22     int T; scanf("%d", &T);
23     while(T--)
24     {
25         scanf("%d%d", &n, &m);
26         for(int i = 1; i <= m; i++) scanf("%d%d", &a[i], &b[i]);
27         int v0 = output(0);
28         int vn = output(n);
29
30         if(v0 == vn)
31             for(int i = 0; i < n; i++) putchar(‘0‘);
32         else
33         {
34             int L = 1, R = n;
35             while(L < R)
36             {
37                 int M = (L + R) / 2;
38                 if(output(M) == vn) R = M;
39                 else L = M + 1;
40             }
41             for(int i = 1; i < L; i++) putchar(‘0‘);
42             putchar(‘x‘);
43             for(int i = L + 1; i <= n; i++) putchar(‘1‘);
44         }
45         printf("\n");
46     }
47
48     return 0;
49 }

代码君

时间: 2024-10-16 15:12:41

UVa 1607 (二分) Gates的相关文章

uva 1607 Gates (uf)

In contemporary VLSI chip industry, the software tools used by electrical engineers perform many optimizations. Your task is to implement one specific optimization of some chip design. Your tool is given an acyclic net of NAND gates (NAND gate comput

UVa 1607 - Gates

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4482 题意: 可以用与非门(NAND)来设计逻辑电路.每个NAND门有两个输入端,输出为两个输入端与非运算的结果.即输出0当且仅当两个输入都是1.给出一个由m(m≤200000)个NAND组成的无环电路,电路的所有n个输入(n≤100000)全部连接到一个相同的输入x.请把其中一些

UVa 1475 (二分+半平面交) Jungle Outpost

题意: 有n个瞭望塔构成一个凸n边形,敌人会炸毁一些瞭望台,剩下的瞭望台构成新的凸包.在凸多边形内部选择一个点作为总部,使得敌人需要炸毁的瞭望塔最多才能使总部暴露出来.输出敌人需要炸毁的数目. 分析: 在炸毁同样数量的瞭望塔时,如何爆破才能使暴露出的面积最大.那就是集中火力炸掉连续的几个瞭望塔.直觉上是这样的,我不会证明这个结论.因为是连续爆破,所以k次爆破后还保留的部分就是一个半平面,枚举这k个爆破点,如果这些半平面交非空则总部可以设在这里. k值是通过二分来确定的,下界是1,上界是n-3(这

UVa 714 (二分) Copying Books

首先通过二分来确定这种最大值最小的问题. 假设每个区间的和的最大值为x,那么只要判断的时候只要贪心即可. 也就是如果和不超过x就一直往区间里放数,否则就开辟一个新的区间,这样来判断是否k个区间容得下这些数. 还有就是输出也挺麻烦的,借鉴了一下lrj的代码,感觉也是十分巧妙. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 const int maxn = 500 + 10; 6 LL a

UVA 10341 (二分查找+精度)

题意: 给你一个关于x的方程,给出变量的值,求出x: Problem F Solve It Input:standard input Output:standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x+ q*sin(x) + r*cos(x) +s*tan(x) +t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of mult

uva 12097(二分)

就是二分 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const double pi=acos(-1.0); const int maxn=10000+100; int t,n,f; double a[maxn]; const double esp=1e-5;

UVa 10341 (二分求根) Solve It

很水的一道题,因为你发现这个函数是单调递减的,所以二分法求出函数的根即可. 1 #include <cstdio> 2 #include <cmath> 3 //using namespace std; 4 5 const double e = 1e-14; 6 double p, q, r, s, t, u; 7 8 inline double f(double x) 9 { return p*exp(-x) + q*sin(x) + r*cos(x) + s*tan(x) +

UVA 714 二分最大化最小值

题意:输入t表示有多个样例,输入n,group表示有n个数分为group组使每组和最小 #include<iostream> #include<string.h> using namespace std; #define ll long long const int N = 500 + 5; ll a[N]; int vis[N]; ll num,m,group; int solve(int d) { ll sum=0; int k=1; for(int i=0;i<num;

训练指南 UVA- 11865(有向最小生成树 + 朱刘算法 + 二分)

layout: post title: 训练指南 UVA- 11865(有向最小生成树 + 朱刘算法 + 二分) author: "luowentaoaa" catalog: true mathjax: true tags: - 最小生成树 - 图论 - 训练指南 Stream My Contest UVA - 11865 二分带宽,然后判断最小生成树是否小于cost值. #include<bits/stdc++.h> using namespace std; typede