zoukankan      html  css  js  c++  java
  • B1202 [HNOI2005]狡猾的商人 并查集

    其实就是并查集的题。维护一个前缀和,然后用并查集维护前缀和,每次判断是否合理就行了。

    题干:

    Description
    
    刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的。账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), 。当 Ai大于0时表示这个月盈利Ai 元,当 Ai小于0时表示这个月亏损Ai 元。所谓一段时间内的总收入,就是这段时间内每个月的收入额的总和。 刁姹的任务是秘密进行的,为了调查商人的账本,她只好跑到商人那里打工。她趁商人不在时去偷看账本,可是她无法将账本偷出来,每次偷看账本时她都只能看某段时间内账本上记录的收入情况,并且她只能记住这段时间内的总收入。 现在,刁姹总共偷看了m次账本,当然也就记住了m段时间内的总收入,你的任务是根据记住的这些信息来判断账本是不是假的。
    Input
    
    第一行为一个正整数w,其中w < 100,表示有w组数据,即w个账本,需要你判断。每组数据的第一行为两个正整数n和m,其中n < 100,m < 1000,分别表示对应的账本记录了多少个月的收入情况以及偷看了多少次账本。接下来的m行表示刁姹偷看m次账本后记住的m条信息,每条信息占一行,有三个整数s,t和v,表示从第s个月到第t个月(包含第t个月)的总收入为v,这里假设s总是小于等于t。
    Output
    
    包含w行,每行是true或false,其中第i行为true当且仅当第i组数据,即第i个账本不是假的;第i行为false当且仅当第i组数据,即第i个账本是假的。
    Sample Input
    2                                        
    3 3                                      
    1 2 10
    1 3 -5
    3 3 -15
    5 3
    1 5 100
    3 5 50
    1 2 51
    Sample Output
    true 
    false
    HINT

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    int fa[1050],n,m,t,flag = 0;
    int v[1050]; 
    int find(int x)
    {
        if(fa[x] == x)
        {
            return x;
        }
        t = find(fa[x]);
        v[x] += v[fa[x]];
        fa[x] = t;
        return fa[x];
    }
    void work(int x,int y,int z)
    {
        int p = find(x);
        int q = find(y);
        if(p != q)
        {
            fa[p] = q;
            v[p] = v[y] - v[x] - z;
        }
        else if(v[y] - v[x] != z)
        flag = 1;
    }
    int main()
    {
        int w,x,y,z;
        read(w);
        while(w--)
        {
            flag = 0;
            clean(v);
            read(n);read(m);
            duke(i,0,n)
            fa[i] = i;
            duke(i,1,m)
            {
                read(x);read(y);read(z);
                work(x - 1,y,z);
            }
            if(flag)
            printf("false
    ");
            else
            printf("true
    "); 
        }
        return 0; 
    }
    /*
    2               
    3 3
    1 2 10
    1 3 -5
    3 3 -15
    5 3
    1 5 100
    3 5 50
    1 2 51
    */
  • 相关阅读:
    CCF-Python的内置函数们
    CCF2019-03-Python题解
    Find a Number (记忆化+BFS)
    LeetCode15:三数之和(双指针)
    LeetCode:不用加号的加法(位运算)
    剑指Offer43:1~n整数中1出现的次数(数位DP)
    LeetCode190:颠倒二进制(位运算分治! 时间复杂度O(1))
    LeetCode5716:好因子的最大数目(数学、快速幂)
    python学习笔记:python的字符串拼接效率分析
    LeetCode1806:还原排列的最少操作步数(置换群 or 模拟)
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9642635.html
Copyright © 2011-2022 走看看